mirror of
https://github.com/ModOrganizer2/mob.git
synced 2026-07-27 14:07:05 -07:00
@@ -13,7 +13,9 @@ namespace mob
|
||||
|
||||
BOOL WINAPI signal_handler(DWORD) noexcept
|
||||
{
|
||||
gcx().debug(context::generic, "caught sigint");
|
||||
// don't use u8cout, this would lock the global mutex, but the handler
|
||||
// can be called while stuff is being output and the mutex is locked
|
||||
std::wcout << L"sigint, interrupting...\n";
|
||||
task_manager::instance().interrupt_all();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
+1
-1
@@ -397,7 +397,7 @@ std::vector<pr_command::pr_info> pr_command::validate_prs(
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!ask_yes_no("these prs will be ignored; proceed anyway?", false))
|
||||
if (ask_yes_no("these prs will be ignored; proceed anyway?", yn::no) != yn::yes)
|
||||
return {};
|
||||
|
||||
u8cout << "\n";
|
||||
|
||||
+34
-9
@@ -4,6 +4,7 @@
|
||||
#include "../core/conf.h"
|
||||
#include "../core/context.h"
|
||||
#include "../core/op.h"
|
||||
#include "../core/ini.h"
|
||||
#include "../tasks/tasks.h"
|
||||
#include "../tasks/task_manager.h"
|
||||
#include "../utility/threading.h"
|
||||
@@ -360,21 +361,45 @@ bool release_command::check_clean_prefix()
|
||||
if (!fs::exists(prefix))
|
||||
return true;
|
||||
|
||||
u8cout
|
||||
<< "prefix " << path_to_utf8(prefix) << " already exists\n"
|
||||
<< "delete? [Y/n] ";
|
||||
bool saw_file = false;
|
||||
const fs::path log_file = conf().global().get("log_file");
|
||||
const std::string ini_file = default_ini_filename();
|
||||
|
||||
std::wstring s;
|
||||
std::getline(std::wcin, s);
|
||||
|
||||
if (s == L"" || s == L"y" || s == L"Y")
|
||||
for (auto itor : fs::directory_iterator(prefix))
|
||||
{
|
||||
build_command::terminate_msbuild();
|
||||
op::delete_directory(gcx(), prefix);
|
||||
const auto name = itor.path().filename();
|
||||
|
||||
// ignore ini and logs
|
||||
if (name == log_file.filename() || name == ini_file)
|
||||
continue;
|
||||
|
||||
saw_file = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!saw_file)
|
||||
{
|
||||
// empty directory, that's fine
|
||||
return true;
|
||||
}
|
||||
|
||||
const auto q = fmt::format(
|
||||
"prefix {} already exists, delete?", path_to_utf8(prefix));
|
||||
|
||||
if (ask_yes_no(q, yn::no) != yn::yes)
|
||||
return false;
|
||||
|
||||
// the log file might be in this directory, close it now and reopen it
|
||||
// when deletion is finished
|
||||
context::close_log_file();
|
||||
|
||||
build_command::terminate_msbuild();
|
||||
op::delete_directory(gcx(), prefix);
|
||||
|
||||
// reopen log file
|
||||
conf().set_log_file();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void release_command::prepare()
|
||||
|
||||
+16
-5
@@ -401,6 +401,13 @@ void process_option(
|
||||
|
||||
// task must exist
|
||||
const auto& tasks = task_manager::instance().find(task);
|
||||
|
||||
if (tasks.empty())
|
||||
{
|
||||
gcx().bail_out(context::conf,
|
||||
"bad option {}, task '{}' not found", section_string, task);
|
||||
}
|
||||
|
||||
MOB_ASSERT(!tasks.empty());
|
||||
|
||||
for (auto& t : tasks)
|
||||
@@ -522,6 +529,14 @@ void resolve_paths()
|
||||
details::set_string("tools", "iscc", path_to_utf8(find_iscc()));
|
||||
}
|
||||
|
||||
void conf::set_log_file()
|
||||
{
|
||||
// set up the log file, resolve against prefix if relative
|
||||
fs::path log_file = conf().global().get("log_file");
|
||||
if (log_file.is_relative())
|
||||
log_file = conf().path().prefix() / log_file;
|
||||
}
|
||||
|
||||
void init_options(
|
||||
const std::vector<fs::path>& inis, const std::vector<std::string>& opts)
|
||||
{
|
||||
@@ -596,11 +611,7 @@ void init_options(
|
||||
resolve_path("prefix", prefix_root, "");
|
||||
|
||||
// set up the log file, resolve against prefix if relative
|
||||
fs::path log_file = conf().global().get("log_file");
|
||||
if (log_file.is_relative())
|
||||
log_file = conf().path().prefix() / log_file;
|
||||
|
||||
context::set_log_file(log_file);
|
||||
conf().set_log_file();
|
||||
|
||||
// goes through all paths and tools, finds missing or relative stuff, bails
|
||||
// out of stuff can't be found
|
||||
|
||||
@@ -242,6 +242,10 @@ public:
|
||||
conf_prebuilt prebuilt();
|
||||
conf_versions version();
|
||||
conf_paths path();
|
||||
|
||||
// opens the log file, creates the directory if needed
|
||||
//
|
||||
void set_log_file();
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -248,6 +248,11 @@ void context::set_log_file(const fs::path& p)
|
||||
}
|
||||
}
|
||||
|
||||
void context::close_log_file()
|
||||
{
|
||||
g_log_file.reset();
|
||||
}
|
||||
|
||||
void context::log_string(reason r, level lv, std::string_view s) const
|
||||
{
|
||||
if (!enabled(lv))
|
||||
|
||||
@@ -148,6 +148,10 @@ public:
|
||||
//
|
||||
static void set_log_file(const fs::path& p);
|
||||
|
||||
// closes the output file for logs, see release_command::check_clean_prefix()
|
||||
//
|
||||
static void close_log_file();
|
||||
|
||||
|
||||
// creates a context for a task; the global context has no name
|
||||
//
|
||||
|
||||
@@ -27,5 +27,6 @@ struct ini_data
|
||||
};
|
||||
|
||||
ini_data parse_ini(const fs::path& ini);
|
||||
std::string default_ini_filename();
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -24,6 +24,8 @@ void mob_assertion_failed(
|
||||
|
||||
if (IsDebuggerPresent())
|
||||
DebugBreak();
|
||||
else
|
||||
std::exit(1);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
+10
-4
@@ -81,24 +81,30 @@ std::mutex& global_output_mutex()
|
||||
return g_output_mutex;
|
||||
}
|
||||
|
||||
bool ask_yes_no(const std::string& text, bool def)
|
||||
yn ask_yes_no(const std::string& text, yn def)
|
||||
{
|
||||
u8cout
|
||||
<< text
|
||||
<< (text.empty() ? "" : " ")
|
||||
<< (def ? "[Y/n]" : "[y/N]")
|
||||
<< (def == yn::yes ? "[Y/n]" : "[y/N]")
|
||||
<< " ";
|
||||
|
||||
// stdin is not utf8
|
||||
std::string line;
|
||||
std::getline(std::cin, line);
|
||||
|
||||
// ctrl+c
|
||||
if (!std::cin)
|
||||
return yn::cancelled;
|
||||
|
||||
if (line.empty())
|
||||
return def;
|
||||
else if (line == "y" || line == "Y")
|
||||
return true;
|
||||
return yn::yes;
|
||||
else if (line == "n" || line == "N")
|
||||
return yn::no;
|
||||
else
|
||||
return false;
|
||||
return yn::cancelled;
|
||||
}
|
||||
|
||||
|
||||
|
||||
+9
-1
@@ -102,9 +102,17 @@ void set_std_streams();
|
||||
//
|
||||
std::mutex& global_output_mutex();
|
||||
|
||||
|
||||
enum class yn
|
||||
{
|
||||
no = 0,
|
||||
yes,
|
||||
cancelled
|
||||
};
|
||||
|
||||
// asks the user for y/n
|
||||
//
|
||||
bool ask_yes_no(const std::string& text, bool def);
|
||||
yn ask_yes_no(const std::string& text, yn def);
|
||||
|
||||
|
||||
// see https://github.com/isanae/mob/issues/4
|
||||
|
||||
@@ -19,9 +19,9 @@ static LPTOP_LEVEL_EXCEPTION_FILTER g_previous_handler = nullptr;
|
||||
|
||||
void dump_stacktrace(const wchar_t* what)
|
||||
{
|
||||
std::scoped_lock lock(global_output_mutex());
|
||||
|
||||
std::wcerr
|
||||
// don't use 8ucout, don't lock the global out mutex, this can be called
|
||||
// while the mutex is locked
|
||||
std::wcerr << what
|
||||
<< "\n\nmob has crashed\n"
|
||||
<< L"*****************************\n\n"
|
||||
<< what << L"\n\n";
|
||||
|
||||
Reference in New Issue
Block a user