task_manager

This commit is contained in:
isanae
2020-12-03 17:45:35 -05:00
parent 1872fc90f6
commit e49735d4ff
16 changed files with 331 additions and 253 deletions
+5 -2
View File
@@ -1,7 +1,10 @@
#include "pch.h"
#include "commands.h"
#include "../core/ini.h"
#include "../tasks/tasks.h"
#include "../core/conf.h"
#include "../core/context.h"
#include "../core/op.h"
#include "../tasks/task_manager.h"
namespace mob
{
@@ -154,7 +157,7 @@ int build_command::do_run()
{
create_prefix_ini();
run_all_tasks();
task_manager::instance().run_all();
if (!keep_msbuild_)
terminate_msbuild();
+1 -1
View File
@@ -89,7 +89,7 @@ clipp::group command::common_options_group()
% "sets an option, such as 'versions/openssl=1.2'",
(clipp::option("--no-default-inis") >> o.no_default_inis)
% "disables auto loading of ini files, only uses --ini; the first"
% "disables auto loading of ini files, only uses --ini; the first "
"--ini must be the master ini file";
}
+8 -4
View File
@@ -1,6 +1,8 @@
#include "pch.h"
#include "commands.h"
#include "../tasks/tasks.h"
#include "../tasks/task_manager.h"
#include "../tasks/task.h"
#include "../utility/io.h"
namespace mob
{
@@ -37,6 +39,8 @@ clipp::group list_command::do_group()
int list_command::do_run()
{
auto& tm = task_manager::instance();
if (aliases_)
{
load_options();
@@ -50,14 +54,14 @@ int list_command::do_run()
set_task_enabled_flags(tasks_);
load_options();
dump(get_top_level_tasks(), 0);
dump(tm.top_level(), 0);
u8cout << "\n\naliases:\n";
dump_aliases();
}
else
{
for (auto&& t : get_all_tasks())
for (auto&& t : tm.all())
u8cout << " - " << join(t->names(), ", ") << "\n";
}
}
@@ -85,7 +89,7 @@ void list_command::dump(const std::vector<task*>& v, std::size_t indent) const
void list_command::dump_aliases() const
{
const auto v = get_all_aliases();
const auto v = task_manager::instance().aliases();
if (v.empty())
return;
+7 -4
View File
@@ -1,6 +1,9 @@
#include "pch.h"
#include "commands.h"
#include "../core/conf.h"
#include "../tasks/task_manager.h"
#include "../tasks/tasks.h"
#include "../utility.h"
namespace mob
{
@@ -95,7 +98,7 @@ std::pair<const tasks::modorganizer*, std::string> pr_command::parse_pr(
const std::string pattern = cs[0];
const std::string pr_number = cs[1];
const auto* task = find_one_task(pattern);
const auto* task = task_manager::instance().find_one(pattern);
if (!task)
return {};
@@ -124,7 +127,7 @@ int pr_command::pull()
for (auto&& pr : okay_prs)
{
const auto* task = dynamic_cast<const tasks::modorganizer*>(
find_one_task(pr.repo));
task_manager::instance().find_one(pr.repo));
if (!task)
return 1;
@@ -173,7 +176,7 @@ int pr_command::revert()
for (auto&& pr : okay_prs)
{
const auto* task = dynamic_cast<const tasks::modorganizer*>(
find_one_task(pr.repo));
task_manager::instance().find_one(pr.repo));
if (!task)
return 1;
@@ -346,7 +349,7 @@ std::vector<pr_command::pr_info> pr_command::validate_prs(
}
else
{
const auto tasks = find_tasks(pr.repo);
const auto tasks = task_manager::instance().find(pr.repo);
if (tasks.empty())
{
+3 -2
View File
@@ -5,6 +5,7 @@
#include "../core/context.h"
#include "../core/op.h"
#include "../tasks/tasks.h"
#include "../tasks/task_manager.h"
#include "../utility/threading.h"
namespace mob
@@ -302,7 +303,7 @@ int release_command::do_official()
if (!check_clean_prefix())
return 1;
run_all_tasks();
task_manager::instance().run_all();
build_command::terminate_msbuild();
prepare();
@@ -321,7 +322,7 @@ void release_command::check_repos_for_branch()
thread_pool tp;
std::atomic<bool> failed = false;
for (const auto* t : find_tasks("super"))
for (const auto* t : task_manager::instance().find("super"))
{
if (!t->enabled())
continue;
+8 -5
View File
@@ -6,6 +6,7 @@
#include "paths.h"
#include "../utility.h"
#include "../tasks/task.h"
#include "../tasks/task_manager.h"
#include "../tools/tools.h"
namespace mob::details
@@ -156,7 +157,7 @@ std::string get_string_for_task(
// for super
for (auto&& tn : task_names)
{
for (auto&& t : find_tasks(tn))
for (auto&& t : task_manager::instance().find(tn))
{
if (t->is_super())
{
@@ -217,6 +218,8 @@ namespace mob
std::vector<std::string> format_options()
{
auto& tm = task_manager::instance();
std::size_t longest_what = 0;
std::size_t longest_key = 0;
@@ -231,7 +234,7 @@ std::vector<std::string> format_options()
for (auto&& [k, v] : details::g_tasks[""])
longest_key = std::max(longest_key, k.size());
for (const auto* task : get_all_tasks())
for (const auto* task : tm.all())
longest_what = std::max(longest_what, task->name().size());
std::vector<std::string> lines;
@@ -263,7 +266,7 @@ std::vector<std::string> format_options()
pad_right(k, longest_key) + " = " + v);
}
for (const auto* t : get_all_tasks())
for (const auto* t : tm.all())
{
for (auto&& [k, unused] : details::g_tasks[""])
{
@@ -395,7 +398,7 @@ void process_option(
// task specific
// task must exist
const auto& tasks = find_tasks(task);
const auto& tasks = task_manager::instance().find(task);
MOB_ASSERT(!tasks.empty());
for (auto& t : tasks)
@@ -429,7 +432,7 @@ void process_ini(const fs::path& ini, bool master)
const auto data = parse_ini(ini);
for (auto&& a : data.aliases)
add_alias(a.first, a.second);
task_manager::instance().add_alias(a.first, a.second);
for (auto&& [section_string, kvs] : data.sections)
{
+5 -3
View File
@@ -4,7 +4,7 @@
#include "context.h"
#include "env.h"
#include "conf.h"
#include "../tasks/tasks.h"
#include "../tasks/task_manager.h"
#include "../utility/string.h"
namespace mob
@@ -220,6 +220,8 @@ void parse_line(
ini_data& ini, std::size_t i, const std::string& line,
const std::string& task, const std::string& section)
{
auto& tm = task_manager::instance();
const auto sep = line.find("=");
if (sep == std::string::npos)
ini_error(ini, i, "bad line '{}'", line);
@@ -232,7 +234,7 @@ void parse_line(
if (section == "aliases")
{
add_alias(k, split_quoted(v, " "));
tm.add_alias(k, split_quoted(v, " "));
}
else if (task.empty())
{
@@ -240,7 +242,7 @@ void parse_line(
}
else
{
if (!valid_task_name(task))
if (!tm.valid_name(task))
ini_error(ini, i, "no task matching '{}' found", task);
ini.set(task + ":" + section, k, v);
+2 -1
View File
@@ -1,5 +1,6 @@
#include "pch.h"
#include "paths.h"
#include "../tasks/task_manager.h"
#include "../tasks/tasks.h"
#include "../utility/string.h"
@@ -337,7 +338,7 @@ fs::path find_qt()
fs::path find_iscc()
{
// don't bother if the installer isn't enabled, it might fail anyway
if (!find_one_task("installer")->enabled())
if (!task_manager::instance().find_one("installer")->enabled())
return {};
// check from the ini first, supports both relative and absolute
+1
View File
@@ -5,6 +5,7 @@
#include "core/conf.h"
#include "core/op.h"
#include "tasks/tasks.h"
#include "tasks/task_manager.h"
#include "tools/tools.h"
#include "utility/threading.h"
+3 -204
View File
@@ -1,5 +1,6 @@
#include "pch.h"
#include "task.h"
#include "task_manager.h"
#include "../core/conf.h"
#include "../core/op.h"
#include "../tools/tools.h"
@@ -8,204 +9,6 @@
namespace mob
{
class interrupted {};
static std::vector<std::unique_ptr<task>> g_top_level_tasks;
static std::vector<task*> g_all_tasks;
static std::atomic<bool> g_interrupt = false;
static alias_map g_aliases;
std::mutex task::interrupt_mutex_;
void add_task(std::unique_ptr<task> t)
{
g_top_level_tasks.push_back(std::move(t));
}
std::vector<task*> get_all_tasks()
{
std::vector<task*> v;
for (auto&& t : g_all_tasks)
v.push_back(t);
return v;
}
std::vector<task*> get_top_level_tasks()
{
std::vector<task*> v;
for (auto&& t : g_top_level_tasks)
v.push_back(t.get());
return v;
}
std::vector<task*> find_tasks_by_pattern(std::string_view pattern)
{
std::vector<task*> tasks;
for (auto&& t : g_all_tasks)
{
if (pattern == "super" && t->is_super())
{
tasks.push_back(t);
}
else
{
for (auto&& n : t->names())
{
if (mob::glob_match(pattern, n))
{
tasks.push_back(t);
break;
}
}
}
}
return tasks;
}
std::vector<task*> find_tasks_by_alias(std::string_view pattern)
{
std::vector<task*> v;
auto itor = g_aliases.find(pattern);
if (itor == g_aliases.end())
return v;
for (auto&& a : itor->second)
{
const auto temp = find_tasks_by_pattern(a);
v.insert(v.end(), temp.begin(), temp.end());
}
return v;
}
std::vector<task*> find_tasks(std::string_view pattern)
{
std::vector<task*> tasks;
for (auto&& t : g_all_tasks)
{
if (pattern == "super" && t->is_super())
{
tasks.push_back(t);
}
else
{
for (auto&& n : t->names())
{
if (mob::glob_match(pattern, n))
{
tasks.push_back(t);
break;
}
}
}
}
if (tasks.empty())
tasks = find_tasks_by_alias(pattern);
return tasks;
}
task* find_one_task(std::string_view pattern, bool verbose)
{
const auto tasks = find_tasks(pattern);
if (tasks.empty())
{
if (verbose)
u8cerr << "no task matches '" << pattern << "'\n";
return nullptr;
}
else if (tasks.size() > 1)
{
if (verbose)
{
u8cerr
<< "found " << tasks.size() << " matches for pattern "
<< "'" << pattern << "'\n"
<< "the pattern must only match one task\n";
}
return nullptr;
}
return tasks[0];
}
bool valid_task_name(std::string_view pattern)
{
if (!find_tasks(pattern).empty())
return true;
if (pattern == "_override")
return true;
return false;
}
void run_all_tasks()
{
try
{
for (auto& t : g_top_level_tasks)
{
t->fetch();
if (g_interrupt)
throw interrupted();
}
for (auto& t : g_top_level_tasks)
{
t->join();
if (g_interrupt)
throw interrupted();
t->build_and_install();
if (g_interrupt)
throw interrupted();
t->join();
if (g_interrupt)
throw interrupted();
}
}
catch(interrupted&)
{
}
}
void add_alias(std::string name, std::vector<std::string> names)
{
auto itor = g_aliases.find(name);
if (itor != g_aliases.end())
{
gcx().warning(context::generic, "alias {} already exists", name);
return;
}
g_aliases.emplace(std::move(name), std::move(names));
}
const alias_map& get_all_aliases()
{
return g_aliases;
}
std::string to_string(task::clean c)
{
// generate warnings if something is added
@@ -361,7 +164,7 @@ task::task(std::vector<std::string> names)
std::this_thread::get_id(), context(name())));
if (name() != "parallel")
g_all_tasks.push_back(this);
task_manager::instance().register_task(this);
}
task::~task()
@@ -414,11 +217,7 @@ void task::add_name(std::string s)
void task::interrupt_all()
{
std::scoped_lock lock(interrupt_mutex_);
g_interrupt = true;
for (auto&& t : g_top_level_tasks)
t->interrupt();
task_manager::instance().interrupt_all();
}
const std::string& task::name() const
-26
View File
@@ -10,30 +10,6 @@ namespace mob
class task;
class tool;
void add_task(std::unique_ptr<task> t);
template <class Task, class... Args>
Task& add_task(Args&&... args)
{
auto sp = std::make_unique<Task>(std::forward<Args>(args)...);
auto* p = sp.get();
add_task(std::move(sp));
return *p;
}
void run_all_tasks();
bool is_super_task(const std::string& name);
std::vector<task*> find_tasks(std::string_view pattern);
task* find_one_task(std::string_view pattern, bool verbose=true);
bool valid_task_name(std::string_view pattern);
std::vector<task*> get_all_tasks();
std::vector<task*> get_top_level_tasks();
using alias_map = std::map<std::string, std::vector<std::string>, std::less<>>;
void add_alias(std::string name, std::vector<std::string> patterns);
const alias_map& get_all_aliases();
class task_conf_holder
{
@@ -146,8 +122,6 @@ private:
std::vector<tool*> tools_;
mutable std::mutex tools_mutex_;
static std::mutex interrupt_mutex_;
clean make_clean_flags() const;
void run_tool_impl(tool* t);
};
+220
View File
@@ -0,0 +1,220 @@
#include "pch.h"
#include "task_manager.h"
#include "task.h"
namespace mob
{
task_manager::task_manager()
: interrupt_(false)
{
}
task_manager& task_manager::instance()
{
static task_manager m;
return m;
}
void task_manager::add(std::unique_ptr<task> t)
{
top_level_.push_back(std::move(t));
}
std::vector<task*> task_manager::find(std::string_view pattern)
{
std::vector<task*> tasks;
for (auto&& t : all_)
{
if (pattern == "super" && t->is_super())
{
tasks.push_back(t);
}
else
{
for (auto&& n : t->names())
{
if (mob::glob_match(pattern, n))
{
tasks.push_back(t);
break;
}
}
}
}
if (tasks.empty())
tasks = find_by_alias(pattern);
return tasks;
}
task* task_manager::find_one(std::string_view pattern, bool verbose)
{
const auto tasks = find(pattern);
if (tasks.empty())
{
if (verbose)
u8cerr << "no task matches '" << pattern << "'\n";
return nullptr;
}
else if (tasks.size() > 1)
{
if (verbose)
{
u8cerr
<< "found " << tasks.size() << " matches for pattern "
<< "'" << pattern << "'\n"
<< "the pattern must only match one task\n";
}
return nullptr;
}
return tasks[0];
}
std::vector<task*> task_manager::all()
{
std::vector<task*> v;
for (auto&& t : all_)
v.push_back(t);
return v;
}
std::vector<task*> task_manager::top_level()
{
std::vector<task*> v;
for (auto&& t : top_level_)
v.push_back(t.get());
return v;
}
void task_manager::add_alias(std::string name, std::vector<std::string> names)
{
auto itor = aliases_.find(name);
if (itor != aliases_.end())
{
gcx().warning(context::generic, "alias {} already exists", name);
return;
}
aliases_.emplace(std::move(name), std::move(names));
}
const task_manager::alias_map& task_manager::aliases()
{
return aliases_;
}
void task_manager::run_all()
{
try
{
for (auto& t : top_level_)
{
t->fetch();
if (interrupt_)
throw interrupted();
}
for (auto& t : top_level_)
{
t->join();
if (interrupt_)
throw interrupted();
t->build_and_install();
if (interrupt_)
throw interrupted();
t->join();
if (interrupt_)
throw interrupted();
}
}
catch(interrupted&)
{
}
}
void task_manager::interrupt_all()
{
std::scoped_lock lock(interrupt_mutex_);
interrupt_ = true;
for (auto&& t : top_level_)
t->interrupt();
}
void task_manager::register_task(task* t)
{
all_.push_back(t);
}
std::vector<task*> task_manager::find_by_pattern(std::string_view pattern)
{
std::vector<task*> tasks;
for (auto&& t : all_)
{
if (pattern == "super" && t->is_super())
{
tasks.push_back(t);
}
else
{
for (auto&& n : t->names())
{
if (mob::glob_match(pattern, n))
{
tasks.push_back(t);
break;
}
}
}
}
return tasks;
}
std::vector<task*> task_manager::find_by_alias(std::string_view pattern)
{
std::vector<task*> v;
auto itor = aliases_.find(pattern);
if (itor == aliases_.end())
return v;
for (auto&& a : itor->second)
{
const auto temp = find_by_pattern(a);
v.insert(v.end(), temp.begin(), temp.end());
}
return v;
}
bool task_manager::valid_name(std::string_view pattern)
{
if (!find(pattern).empty())
return true;
if (pattern == "_override")
return true;
return false;
}
} // namespace
+58
View File
@@ -0,0 +1,58 @@
#pragma once
namespace mob
{
class interrupted {};
class task;
class task_manager
{
public:
using alias_map =
std::map<std::string, std::vector<std::string>, std::less<>>;
task_manager();
static task_manager& instance();
void add(std::unique_ptr<task> t);
std::vector<task*> find(std::string_view pattern);
task* find_one(std::string_view pattern, bool verbose=true);
bool valid_name(std::string_view pattern);
std::vector<task*> all();
std::vector<task*> top_level();
void add_alias(std::string name, std::vector<std::string> patterns);
const alias_map& aliases();
void run_all();
void interrupt_all();
void register_task(task* t);
private:
std::vector<std::unique_ptr<task>> top_level_;
std::vector<task*> all_;
std::atomic<bool> interrupt_;
std::mutex interrupt_mutex_;
alias_map aliases_;
std::vector<task*> find_by_pattern(std::string_view pattern);
std::vector<task*> find_by_alias(std::string_view pattern);
};
template <class Task, class... Args>
Task& add_task(Args&&... args)
{
auto t = std::make_unique<Task>(std::forward<Args>(args)...);
auto& ref = *t;
task_manager::instance().add(std::move(t));
return ref;
}
} // namespace
+2 -1
View File
@@ -1,5 +1,6 @@
#include "pch.h"
#include "tasks.h"
#include "task_manager.h"
#include "../core/env.h"
#include "../utility/threading.h"
@@ -48,7 +49,7 @@ void translations::projects::create()
bool translations::projects::is_gamebryo_plugin(
const std::string& dir, const std::string& project)
{
auto tasks = find_tasks(project);
auto tasks = task_manager::instance().find(project);
if (tasks.empty())
{
warnings_.push_back(::fmt::format(
+2
View File
@@ -103,6 +103,7 @@
<ClCompile Include="..\src\tasks\spdlog.cpp" />
<ClCompile Include="..\src\tasks\stylesheets.cpp" />
<ClCompile Include="..\src\tasks\task.cpp" />
<ClCompile Include="..\src\tasks\task_manager.cpp" />
<ClCompile Include="..\src\tasks\translations.cpp" />
<ClCompile Include="..\src\tasks\usvfs.cpp" />
<ClCompile Include="..\src\tasks\zlib.cpp" />
@@ -137,6 +138,7 @@
<ClInclude Include="..\src\pch.h" />
<ClInclude Include="..\src\tasks\task.h" />
<ClInclude Include="..\src\tasks\tasks.h" />
<ClInclude Include="..\src\tasks\task_manager.h" />
<ClInclude Include="..\src\tools\cmake.h" />
<ClInclude Include="..\src\tools\git.h" />
<ClInclude Include="..\src\tools\msbuild.h" />
+6
View File
@@ -204,6 +204,9 @@
<ClCompile Include="..\src\tools\python.cpp">
<Filter>src\tools</Filter>
</ClCompile>
<ClCompile Include="..\src\tasks\task_manager.cpp">
<Filter>src\tasks</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\src\pch.h">
@@ -281,5 +284,8 @@
<ClInclude Include="..\src\tools\msbuild.h">
<Filter>src\tools</Filter>
</ClInclude>
<ClInclude Include="..\src\tasks\task_manager.h">
<Filter>src\tasks</Filter>
</ClInclude>
</ItemGroup>
</Project>