Merge pull request #120 from ModOrganizer2/dev/formatting-and-ci

Formatting and CI
This commit is contained in:
Mikaël Capelle
2023-09-23 15:19:04 +02:00
committed by GitHub
92 changed files with 18563 additions and 20464 deletions
+26
View File
@@ -0,0 +1,26 @@
---
# We'll use defaults from the LLVM style, but with 4 columns indentation.
BasedOnStyle: LLVM
IndentWidth: 4
---
Language: Cpp
# Force pointers to the type for C++.
DerivePointerAlignment: false
PointerAlignment: Left
AlignConsecutiveAssignments: true
AllowShortFunctionsOnASingleLine: Inline
AllowShortIfStatementsOnASingleLine: Never
AllowShortLambdasOnASingleLine: Empty
AlwaysBreakTemplateDeclarations: Yes
AccessModifierOffset: -4
AlignTrailingComments: true
SpacesBeforeTrailingComments: 2
NamespaceIndentation: All
MaxEmptyLinesToKeep: 1
BreakBeforeBraces: Stroustrup
ColumnLimit: 88
IncludeBlocks: Preserve
IncludeCategories:
- Regex: '^"pch.h"$'
Priority: -1
SortPriority: -1
+1
View File
@@ -0,0 +1 @@
d0913d07d33929d7b753a3a09a0dac70e5befbc1
+7
View File
@@ -0,0 +1,7 @@
# Set the default behavior, in case people don't have core.autocrlf set.
* text=auto
# Explicitly declare text files you want to always be normalized and converted
# to native line endings on checkout.
*.cpp text eol=crlf
*.h text eol=crlf
+16
View File
@@ -0,0 +1,16 @@
name: Build Mob
on:
push:
branches: master
pull_request:
types: [opened, synchronize, reopened]
jobs:
build:
runs-on: windows-2022
steps:
- uses: actions/checkout@v4
- name: Build Mob
shell: pwsh
run: ./bootstrap.ps1 -Verbose
+18
View File
@@ -0,0 +1,18 @@
name: Lint Mob
on:
push:
pull_request:
types: [opened, synchronize, reopened]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Run clang-format
uses: jidicula/clang-format-action@v4.11.0
with:
clang-format-version: "16"
check-path: "."
exclude-regex: "third-party"
+150 -155
View File
@@ -1,200 +1,195 @@
#include "pch.h"
#include "commands.h"
#include "../core/ini.h"
#include "../core/conf.h"
#include "../core/context.h"
#include "../core/ini.h"
#include "../core/op.h"
#include "../tasks/task_manager.h"
#include "commands.h"
namespace mob
{
namespace mob {
build_command::build_command()
: command(requires_options | handle_sigint)
{
}
build_command::build_command() : command(requires_options | handle_sigint) {}
command::meta_t build_command::meta() const
{
return
{
"build",
"builds tasks"
};
}
command::meta_t build_command::meta() const
{
return {"build", "builds tasks"};
}
clipp::group build_command::do_group()
{
return
(clipp::command("build")).set(picked_),
clipp::group build_command::do_group()
{
return (clipp::command("build")).set(picked_),
(clipp::option("-h", "--help") >> help_)
% ("shows this message"),
(clipp::option("-h", "--help") >> help_) % ("shows this message"),
(clipp::option("-g", "--redownload") >> redownload_)
% "redownloads archives, see --reextract",
(clipp::option("-g", "--redownload") >> redownload_) %
"redownloads archives, see --reextract",
(clipp::option("-e", "--reextract") >> reextract_)
% "deletes source directories and re-extracts archives",
(clipp::option("-e", "--reextract") >> reextract_) %
"deletes source directories and re-extracts archives",
(clipp::option("-c", "--reconfigure") >> reconfigure_)
% "reconfigures the task by running cmake, configure scripts, "
"etc.; some tasks might have to delete the whole source "
"directory",
(clipp::option("-c", "--reconfigure") >> reconfigure_) %
"reconfigures the task by running cmake, configure scripts, "
"etc.; some tasks might have to delete the whole source "
"directory",
(clipp::option("-b", "--rebuild") >> rebuild_)
% "cleans and rebuilds projects; some tasks might have to "
"delete the whole source directory",
(clipp::option("-b", "--rebuild") >> rebuild_) %
"cleans and rebuilds projects; some tasks might have to "
"delete the whole source directory",
(clipp::option("-n", "--new") >> new_)
% "deletes everything and starts from scratch",
(clipp::option("-n", "--new") >> new_) %
"deletes everything and starts from scratch",
(
clipp::option("--clean-task").call([&]{ clean_ = true; }) |
clipp::option("--no-clean-task").call([&]{ clean_ = false; })
) % "sets whether tasks are cleaned",
(clipp::option("--clean-task").call([&] {
clean_ = true;
}) |
clipp::option("--no-clean-task").call([&] {
clean_ = false;
})) %
"sets whether tasks are cleaned",
(
clipp::option("--fetch-task").call([&]{ fetch_ = true; }) |
clipp::option("--no-fetch-task").call([&]{ fetch_ = false; })
) % "sets whether tasks are fetched",
(clipp::option("--fetch-task").call([&] {
fetch_ = true;
}) |
clipp::option("--no-fetch-task").call([&] {
fetch_ = false;
})) %
"sets whether tasks are fetched",
(
clipp::option("--build-task").call([&]{ build_ = true; }) |
clipp::option("--no-build-task").call([&]{ build_ = false; })
) % "sets whether tasks are built",
(clipp::option("--build-task").call([&] {
build_ = true;
}) |
clipp::option("--no-build-task").call([&] {
build_ = false;
})) %
"sets whether tasks are built",
(
clipp::option("--pull").call([&]{ nopull_ = false; }) |
clipp::option("--no-pull").call([&]{ nopull_ = true; })
) % "whether to pull repos that are already cloned; global override",
(clipp::option("--pull").call([&] {
nopull_ = false;
}) |
clipp::option("--no-pull").call([&] {
nopull_ = true;
})) %
"whether to pull repos that are already cloned; global override",
(
clipp::option("--revert-ts").call([&]{ revert_ts_ = true; }) |
clipp::option("--no-revert-ts").call([&]{ revert_ts_ = false; })
) % "whether to revert all the .ts files in a repo before pulling to "
"avoid merge errors; global override",
(clipp::option("--revert-ts").call([&] {
revert_ts_ = true;
}) |
clipp::option("--no-revert-ts").call([&] {
revert_ts_ = false;
})) %
"whether to revert all the .ts files in a repo before pulling to "
"avoid merge errors; global override",
(clipp::option("--ignore-uncommitted-changes") >> ignore_uncommitted_)
% "when --reextract is given, directories controlled by git will "
"be deleted even if they contain uncommitted changes",
(clipp::option("--ignore-uncommitted-changes") >> ignore_uncommitted_) %
"when --reextract is given, directories controlled by git will "
"be deleted even if they contain uncommitted changes",
(clipp::option("--keep-msbuild") >> keep_msbuild_)
% "don't terminate msbuild.exe instances after building",
(clipp::option("--keep-msbuild") >> keep_msbuild_) %
"don't terminate msbuild.exe instances after building",
(clipp::opt_values(
clipp::match::prefix_not("-"), "task", tasks_))
% "tasks to run; specify 'super' to only build modorganizer "
"projects";
}
(clipp::opt_values(clipp::match::prefix_not("-"), "task", tasks_)) %
"tasks to run; specify 'super' to only build modorganizer "
"projects";
}
void build_command::convert_cl_to_conf()
{
command::convert_cl_to_conf();
void build_command::convert_cl_to_conf()
{
command::convert_cl_to_conf();
if (redownload_ || new_)
common.options.push_back("global/redownload=true");
if (redownload_ || new_)
common.options.push_back("global/redownload=true");
if (reextract_ || new_)
common.options.push_back("global/reextract=true");
if (reextract_ || new_)
common.options.push_back("global/reextract=true");
if (reconfigure_ || new_)
common.options.push_back("global/reconfigure=true");
if (reconfigure_ || new_)
common.options.push_back("global/reconfigure=true");
if (rebuild_ || new_)
common.options.push_back("global/rebuild=true");
if (rebuild_ || new_)
common.options.push_back("global/rebuild=true");
if (ignore_uncommitted_)
common.options.push_back("global/ignore_uncommitted=true");
if (ignore_uncommitted_)
common.options.push_back("global/ignore_uncommitted=true");
if (clean_)
{
if (*clean_)
common.options.push_back("global/clean_task=true");
else
common.options.push_back("global/clean_task=false");
}
if (clean_) {
if (*clean_)
common.options.push_back("global/clean_task=true");
else
common.options.push_back("global/clean_task=false");
}
if (fetch_)
{
if (*fetch_)
common.options.push_back("global/fetch_task=true");
else
common.options.push_back("global/fetch_task=false");
}
if (fetch_) {
if (*fetch_)
common.options.push_back("global/fetch_task=true");
else
common.options.push_back("global/fetch_task=false");
}
if (build_)
{
if (*build_)
common.options.push_back("global/build_task=true");
else
common.options.push_back("global/build_task=false");
}
if (build_) {
if (*build_)
common.options.push_back("global/build_task=true");
else
common.options.push_back("global/build_task=false");
}
if (nopull_)
{
if (*nopull_)
common.options.push_back("_override:task/no_pull=true");
else
common.options.push_back("_override:task/no_pull=false");
}
if (nopull_) {
if (*nopull_)
common.options.push_back("_override:task/no_pull=true");
else
common.options.push_back("_override:task/no_pull=false");
}
if (revert_ts_)
{
if (*revert_ts_)
common.options.push_back("_override:task/revert_ts=true");
else
common.options.push_back("_override:task/revert_ts=false");
}
if (revert_ts_) {
if (*revert_ts_)
common.options.push_back("_override:task/revert_ts=true");
else
common.options.push_back("_override:task/revert_ts=false");
}
if (!tasks_.empty())
set_task_enabled_flags(tasks_);
}
if (!tasks_.empty())
set_task_enabled_flags(tasks_);
}
int build_command::do_run()
{
try
{
create_prefix_ini();
int build_command::do_run()
{
try {
create_prefix_ini();
task_manager::instance().run_all();
task_manager::instance().run_all();
if (!keep_msbuild_)
terminate_msbuild();
if (!keep_msbuild_)
terminate_msbuild();
mob::gcx().info(mob::context::generic, "mob done");
return 0;
}
catch(bailed&)
{
gcx().error(context::generic, "bailing out");
return 1;
}
}
mob::gcx().info(mob::context::generic, "mob done");
return 0;
}
catch (bailed&) {
gcx().error(context::generic, "bailing out");
return 1;
}
}
void build_command::create_prefix_ini()
{
const auto prefix = conf().path().prefix();
void build_command::create_prefix_ini()
{
const auto prefix = conf().path().prefix();
// creating prefix
if (!exists(prefix))
op::create_directories(gcx(), prefix);
// creating prefix
if (!exists(prefix))
op::create_directories(gcx(), prefix);
const auto ini = prefix / default_ini_filename();
if (!exists(ini))
{
std::ofstream(ini)
<< "[paths]\n"
<< "prefix = .\n";
}
}
const auto ini = prefix / default_ini_filename();
if (!exists(ini)) {
std::ofstream(ini) << "[paths]\n"
<< "prefix = .\n";
}
}
void build_command::terminate_msbuild()
{
if (conf().global().dry())
return;
void build_command::terminate_msbuild()
{
if (conf().global().dry())
return;
system("taskkill /im msbuild.exe /f > NUL 2>&1");
}
system("taskkill /im msbuild.exe /f > NUL 2>&1");
}
} // namespace
} // namespace mob
+45 -63
View File
@@ -1,83 +1,65 @@
#include "pch.h"
#include "commands.h"
#include "../tasks/tasks.h"
#include "commands.h"
namespace mob
{
namespace mob {
cmake_command::cmake_command()
: command(requires_options)
{
}
cmake_command::cmake_command() : command(requires_options) {}
command::meta_t cmake_command::meta() const
{
return
{
"cmake",
"runs cmake in a directory"
};
}
command::meta_t cmake_command::meta() const
{
return {"cmake", "runs cmake in a directory"};
}
clipp::group cmake_command::do_group()
{
return clipp::group(
clipp::command("cmake").set(picked_),
clipp::group cmake_command::do_group()
{
return clipp::group(
clipp::command("cmake").set(picked_),
(clipp::option("-h", "--help") >> help_)
% "shows this message",
(clipp::option("-h", "--help") >> help_) % "shows this message",
(clipp::option("-G", "--generator")
& clipp::value("GEN") >> gen_)
% ("sets the -G option for cmake [default: VS]"),
(clipp::option("-G", "--generator") & clipp::value("GEN") >> gen_) %
("sets the -G option for cmake [default: VS]"),
(clipp::option("-c", "--cmd")
& clipp::value("CMD") >> cmd_)
% "overrides the cmake command line [default: \"..\"]",
(clipp::option("-c", "--cmd") & clipp::value("CMD") >> cmd_) %
"overrides the cmake command line [default: \"..\"]",
(
clipp::option("--x64").set(x64_, true) |
clipp::option("--x86").set(x64_, false)
)
% "whether to use the x64 or x86 vcvars; if -G is not set, "
"whether to pass \"-A Win32\" or \"-A x64\" for the default "
"VS generator [default: x64]",
(clipp::option("--x64").set(x64_, true) |
clipp::option("--x86").set(x64_, false)) %
"whether to use the x64 or x86 vcvars; if -G is not set, "
"whether to pass \"-A Win32\" or \"-A x64\" for the default "
"VS generator [default: x64]",
(clipp::option("--install-prefix")
& clipp::value("PATH") >> prefix_)
% "sets CMAKE_INSTALL_PREFIX [default: empty]",
(clipp::option("--install-prefix") & clipp::value("PATH") >> prefix_) %
"sets CMAKE_INSTALL_PREFIX [default: empty]",
(clipp::value("PATH") >> path_)
% "path from which to run `cmake`"
);
}
(clipp::value("PATH") >> path_) % "path from which to run `cmake`");
}
int cmake_command::do_run()
{
auto t = tasks::modorganizer::create_cmake_tool(
fs::path(utf8_to_utf16(path_)));
int cmake_command::do_run()
{
auto t = tasks::modorganizer::create_cmake_tool(fs::path(utf8_to_utf16(path_)));
t.generator(gen_);
t.cmd(cmd_);
t.prefix(prefix_);
t.output(path_);
t.generator(gen_);
t.cmd(cmd_);
t.prefix(prefix_);
t.output(path_);
if (!x64_)
t.architecture(arch::x86);
if (!x64_)
t.architecture(arch::x86);
// copy the global context, the tool will modify it
context cxcopy(gcx());
// copy the global context, the tool will modify it
context cxcopy(gcx());
t.run(cxcopy);
t.run(cxcopy);
return 0;
}
return 0;
}
std::string cmake_command::do_doc()
{
return
"Runs `cmake ..` in the given directory with the same command line\n"
"as the one used for modorganizer projects.";
}
std::string cmake_command::do_doc()
{
return "Runs `cmake ..` in the given directory with the same command line\n"
"as the one used for modorganizer projects.";
}
} // namespace
} // namespace mob
+319 -372
View File
File diff suppressed because it is too large Load Diff
+423 -479
View File
File diff suppressed because it is too large Load Diff
+191 -229
View File
@@ -1,285 +1,247 @@
#include "pch.h"
#include "commands.h"
#include "../tasks/tasks.h"
#include "../tools/tools.h"
#include "commands.h"
namespace mob
{
namespace mob {
git_command::git_command()
: command(requires_options)
{
}
git_command::git_command() : command(requires_options) {}
command::meta_t git_command::meta() const
{
return
{
"git",
"manages the git repos"
};
}
command::meta_t git_command::meta() const
{
return {"git", "manages the git repos"};
}
clipp::group git_command::do_group()
{
return clipp::group(
clipp::command("git").set(picked_),
clipp::group git_command::do_group()
{
return clipp::group(
clipp::command("git").set(picked_),
(clipp::option("-h", "--help") >> help_)
% ("shows this message"),
(clipp::option("-h", "--help") >> help_) % ("shows this message"),
"set-remotes" %
(clipp::command("set-remotes").set(mode_, modes::set_remotes),
(clipp::required("-u", "--username")
& clipp::value("USERNAME") >> username_)
% "git username",
"set-remotes" %
(clipp::command("set-remotes").set(mode_, modes::set_remotes),
(clipp::required("-u", "--username") &
clipp::value("USERNAME") >> username_) %
"git username",
(clipp::required("-e", "--email")
& clipp::value("EMAIL") >> email_)
% "git email",
(clipp::required("-e", "--email") &
clipp::value("EMAIL") >> email_) %
"git email",
(clipp::option("-k", "--key")
& clipp::value("PATH") >> key_)
% "path to putty key",
(clipp::option("-k", "--key") & clipp::value("PATH") >> key_) %
"path to putty key",
(clipp::option("-s", "--no-push").set(nopush_)
% "disables pushing to 'upstream' by changing the push url "
"to 'nopushurl' to avoid accidental pushes"),
(clipp::option("-s", "--no-push").set(nopush_) %
"disables pushing to 'upstream' by changing the push url "
"to 'nopushurl' to avoid accidental pushes"),
(clipp::option("-p", "--push-origin").set(push_default_)
% "sets the new 'origin' remote as the default push target"),
(clipp::option("-p", "--push-origin").set(push_default_) %
"sets the new 'origin' remote as the default push target"),
(clipp::opt_value("path") >> path_)
% "only use this repo"
)
(clipp::opt_value("path") >> path_) % "only use this repo")
|
|
"add-remote" %
(clipp::command("add-remote").set(mode_, modes::add_remote),
(clipp::required("-n", "--name")
& clipp::value("NAME") >> remote_)
% "name of new remote",
"add-remote" %
(clipp::command("add-remote").set(mode_, modes::add_remote),
(clipp::required("-n", "--name") &
clipp::value("NAME") >> remote_) %
"name of new remote",
(clipp::required("-u", "--username")
& clipp::value("USERNAME") >> username_)
% "git username",
(clipp::required("-u", "--username") &
clipp::value("USERNAME") >> username_) %
"git username",
(clipp::option("-k", "--key")
& clipp::value("PATH") >> key_)
% "path to putty key",
(clipp::option("-k", "--key") & clipp::value("PATH") >> key_) %
"path to putty key",
(clipp::option("-p", "--push-origin").set(push_default_)
% "sets this new remote as the default push target"),
(clipp::option("-p", "--push-origin").set(push_default_) %
"sets this new remote as the default push target"),
(clipp::opt_value("path") >> path_)
% "only use this repo"
)
(clipp::opt_value("path") >> path_) % "only use this repo")
|
|
"ignore-ts" %
(clipp::command("ignore-ts").set(mode_, modes::ignore_ts),
(
clipp::command("on").set(tson_, true) |
clipp::command("off").set(tson_, false)
)
)
"ignore-ts" % (clipp::command("ignore-ts").set(mode_, modes::ignore_ts),
(clipp::command("on").set(tson_, true) |
clipp::command("off").set(tson_, false)))
|
|
"branches" %
(clipp::command("branches").set(mode_, modes::branches),
clipp::option("-a", "--all").set(all_branches_)
% "shows all branches, including those on master"
)
);
}
"branches" % (clipp::command("branches").set(mode_, modes::branches),
clipp::option("-a", "--all").set(all_branches_) %
"shows all branches, including those on master"));
}
int git_command::do_run()
{
switch (mode_)
{
case modes::set_remotes:
{
do_set_remotes();
break;
}
int git_command::do_run()
{
switch (mode_) {
case modes::set_remotes: {
do_set_remotes();
break;
}
case modes::add_remote:
{
do_add_remote();
break;
}
case modes::add_remote: {
do_add_remote();
break;
}
case modes::ignore_ts:
{
do_ignore_ts();
break;
}
case modes::ignore_ts: {
do_ignore_ts();
break;
}
case modes::branches:
{
do_branches();
break;
}
case modes::branches: {
do_branches();
break;
}
case modes::none:
default:
u8cerr << "bad git mode " << static_cast<int>(mode_) << "\n";
throw bailed();
}
case modes::none:
default:
u8cerr << "bad git mode " << static_cast<int>(mode_) << "\n";
throw bailed();
}
return 0;
}
return 0;
}
std::string git_command::do_doc()
{
return
"All the commands will go through all modorganizer repos, plus usvfs\n"
"and NCC.\n"
"\n"
"Commands:\n"
"set-remotes\n"
" For each repo, this first sets the username and email. Then, it\n"
" will rename the remote 'origin' to 'upstream' and create a new\n"
" remote 'origin' with the given information. If the remote\n"
" 'upstream' already exists in a repo, nothing happens.\n"
"\n"
"add-remote\n"
" For each repo, adds a new remote with the given information. If a\n"
" remote with the same name already exists, nothing happens.\n"
"\n"
"ignore-ts\n"
" Toggles the --assume-changed status of all .ts files in all repos.\n"
"\n"
"branches\n"
" Lists all git repos that are not on master. With -a, show all \n"
" repos and their current branch.";
}
std::string git_command::do_doc()
{
return "All the commands will go through all modorganizer repos, plus usvfs\n"
"and NCC.\n"
"\n"
"Commands:\n"
"set-remotes\n"
" For each repo, this first sets the username and email. Then, it\n"
" will rename the remote 'origin' to 'upstream' and create a new\n"
" remote 'origin' with the given information. If the remote\n"
" 'upstream' already exists in a repo, nothing happens.\n"
"\n"
"add-remote\n"
" For each repo, adds a new remote with the given information. If a\n"
" remote with the same name already exists, nothing happens.\n"
"\n"
"ignore-ts\n"
" Toggles the --assume-changed status of all .ts files in all repos.\n"
"\n"
"branches\n"
" Lists all git repos that are not on master. With -a, show all \n"
" repos and their current branch.";
}
void git_command::do_set_remotes()
{
if (path_.empty())
{
const auto repos = get_repos();
void git_command::do_set_remotes()
{
if (path_.empty()) {
const auto repos = get_repos();
for (auto&& r : repos)
do_set_remotes(r);
}
else
{
do_set_remotes(path_);
}
}
for (auto&& r : repos)
do_set_remotes(r);
}
else {
do_set_remotes(path_);
}
}
void git_command::do_set_remotes(const fs::path& r)
{
u8cout << "setting up " << path_to_utf8(r.filename()) << "\n";
void git_command::do_set_remotes(const fs::path& r)
{
u8cout << "setting up " << path_to_utf8(r.filename()) << "\n";
git_wrap(r).set_credentials(username_, email_);
git_wrap(r).set_credentials(username_, email_);
git_wrap(r).set_origin_and_upstream_remotes(
username_, key_, nopush_, push_default_);
}
git_wrap(r).set_origin_and_upstream_remotes(username_, key_, nopush_,
push_default_);
}
void git_command::do_add_remote()
{
u8cout
<< "adding remote '" << remote_ << "' "
<< "from '" << username_ << "' to repos\n";
void git_command::do_add_remote()
{
u8cout << "adding remote '" << remote_ << "' "
<< "from '" << username_ << "' to repos\n";
if (path_.empty())
{
const auto repos = get_repos();
if (path_.empty()) {
const auto repos = get_repos();
for (auto&& r : repos)
do_add_remote(r);
}
else
{
do_add_remote(path_);
}
}
for (auto&& r : repos)
do_add_remote(r);
}
else {
do_add_remote(path_);
}
}
void git_command::do_add_remote(const fs::path& r)
{
u8cout << path_to_utf8(r.filename()) << "\n";
git_wrap(r).add_remote(remote_, username_, key_, push_default_);
}
void git_command::do_add_remote(const fs::path& r)
{
u8cout << path_to_utf8(r.filename()) << "\n";
git_wrap(r).add_remote(remote_, username_, key_, push_default_);
}
void git_command::do_ignore_ts()
{
if (tson_)
u8cout << "ignoring .ts files\n";
else
u8cout << "un-ignoring .ts files\n";
void git_command::do_ignore_ts()
{
if (tson_)
u8cout << "ignoring .ts files\n";
else
u8cout << "un-ignoring .ts files\n";
if (path_.empty())
{
const auto repos = get_repos();
if (path_.empty()) {
const auto repos = get_repos();
for (auto&& r : repos)
do_ignore_ts(r);
}
else
{
do_ignore_ts(path_);
}
}
for (auto&& r : repos)
do_ignore_ts(r);
}
else {
do_ignore_ts(path_);
}
}
void git_command::do_ignore_ts(const fs::path& r)
{
u8cout << path_to_utf8(r.filename()) << "\n";
git_wrap(r).ignore_ts(tson_);
}
void git_command::do_ignore_ts(const fs::path& r)
{
u8cout << path_to_utf8(r.filename()) << "\n";
git_wrap(r).ignore_ts(tson_);
}
void git_command::do_branches()
{
std::vector<std::pair<std::string, std::string>> v;
void git_command::do_branches()
{
std::vector<std::pair<std::string, std::string>> v;
for (auto&& r : get_repos())
{
const auto b = git_wrap(r).current_branch();
if (b == "master" && !all_branches_)
continue;
for (auto&& r : get_repos()) {
const auto b = git_wrap(r).current_branch();
if (b == "master" && !all_branches_)
continue;
if (b.empty())
v.push_back({r.filename().string(), "detached head"});
else
v.push_back({r.filename().string(), b});
}
if (b.empty())
v.push_back({r.filename().string(), "detached head"});
else
v.push_back({r.filename().string(), b});
}
u8cout << table(v, 0, 3) << "\n";
}
u8cout << table(v, 0, 3) << "\n";
}
std::vector<fs::path> git_command::get_repos() const
{
std::vector<fs::path> v;
std::vector<fs::path> git_command::get_repos() const
{
std::vector<fs::path> v;
// usvfs
if (fs::exists(tasks::usvfs::source_path()))
v.push_back(tasks::usvfs::source_path());
// usvfs
if (fs::exists(tasks::usvfs::source_path()))
v.push_back(tasks::usvfs::source_path());
const auto super = tasks::modorganizer::super_path();
const auto super = tasks::modorganizer::super_path();
// all directories in super except for those starting with a dot
if (fs::exists(super))
{
for (auto e : fs::directory_iterator(super))
{
if (!e.is_directory())
continue;
// all directories in super except for those starting with a dot
if (fs::exists(super)) {
for (auto e : fs::directory_iterator(super)) {
if (!e.is_directory())
continue;
const auto p = e.path();
if (path_to_utf8(p.filename()).starts_with("."))
continue;
const auto p = e.path();
if (path_to_utf8(p.filename()).starts_with("."))
continue;
v.push_back(p);
}
}
v.push_back(p);
}
}
return v;
}
return v;
}
} // namespace
} // namespace mob
+62 -79
View File
@@ -1,100 +1,83 @@
#include "pch.h"
#include "commands.h"
#include "../tasks/task_manager.h"
#include "../tasks/task.h"
#include "../tasks/task_manager.h"
#include "../utility/io.h"
#include "commands.h"
namespace mob
{
namespace mob {
command::meta_t list_command::meta() const
{
return
{
"list",
"lists available tasks"
};
}
command::meta_t list_command::meta() const
{
return {"list", "lists available tasks"};
}
clipp::group list_command::do_group()
{
return clipp::group(
clipp::command("list").set(picked_),
clipp::group list_command::do_group()
{
return clipp::group(
clipp::command("list").set(picked_),
(clipp::option("-h", "--help") >> help_)
% "shows this message",
(clipp::option("-h", "--help") >> help_) % "shows this message",
(clipp::option("-a", "--all") >> all_)
% "shows all the tasks, including pseudo parallel tasks",
(clipp::option("-a", "--all") >> all_) %
"shows all the tasks, including pseudo parallel tasks",
(clipp::option("-i", "--aliases") >> aliases_)
% "shows only aliases",
(clipp::option("-i", "--aliases") >> aliases_) % "shows only aliases",
(clipp::opt_values(
clipp::match::prefix_not("-"), "task", tasks_))
% "with -a; when given, acts like the tasks given to `build` and "
"shows only the tasks that would run"
);
}
(clipp::opt_values(clipp::match::prefix_not("-"), "task", tasks_)) %
"with -a; when given, acts like the tasks given to `build` and "
"shows only the tasks that would run");
}
int list_command::do_run()
{
auto& tm = task_manager::instance();
int list_command::do_run()
{
auto& tm = task_manager::instance();
if (aliases_)
{
load_options();
dump_aliases();
}
else
{
if (all_)
{
if (!tasks_.empty())
set_task_enabled_flags(tasks_);
if (aliases_) {
load_options();
dump_aliases();
}
else {
if (all_) {
if (!tasks_.empty())
set_task_enabled_flags(tasks_);
load_options();
dump(tm.top_level(), 0);
load_options();
dump(tm.top_level(), 0);
u8cout << "\n\naliases:\n";
dump_aliases();
}
else
{
for (auto&& t : tm.all())
u8cout << " - " << join(t->names(), ", ") << "\n";
}
}
u8cout << "\n\naliases:\n";
dump_aliases();
}
else {
for (auto&& t : tm.all())
u8cout << " - " << join(t->names(), ", ") << "\n";
}
}
return 0;
}
return 0;
}
void list_command::dump(const std::vector<task*>& v, std::size_t indent) const
{
for (auto&& t : v) {
if (!t->enabled())
continue;
void list_command::dump(const std::vector<task*>& v, std::size_t indent) const
{
for (auto&& t : v)
{
if (!t->enabled())
continue;
u8cout << std::string(indent * 4, ' ') << " - " << join(t->names(), ",")
<< "\n";
u8cout
<< std::string(indent*4, ' ')
<< " - " << join(t->names(), ",")
<< "\n";
if (auto* pt = dynamic_cast<parallel_tasks*>(t))
dump(pt->children(), indent + 1);
}
}
if (auto* pt=dynamic_cast<parallel_tasks*>(t))
dump(pt->children(), indent + 1);
}
}
void list_command::dump_aliases() const
{
const auto v = task_manager::instance().aliases();
if (v.empty())
return;
void list_command::dump_aliases() const
{
const auto v = task_manager::instance().aliases();
if (v.empty())
return;
for (auto&& [k, patterns] : v)
u8cout << " - " << k << ": " << join(patterns, ", ") << "\n";
}
for (auto&& [k, patterns] : v)
u8cout << " - " << k << ": " << join(patterns, ", ") << "\n";
}
} // namespace
} // namespace mob
+358 -403
View File
File diff suppressed because it is too large Load Diff
+525 -587
View File
File diff suppressed because it is too large Load Diff
+141 -166
View File
@@ -1,213 +1,188 @@
#include "pch.h"
#include "commands.h"
#include "../net.h"
#include "../utility.h"
#include "../core/conf.h"
#include "../core/context.h"
#include "../core/env.h"
#include "../net.h"
#include "../tasks/tasks.h"
#include "../utility.h"
#include "commands.h"
namespace mob
{
namespace mob {
tx_command::tx_command()
: command(requires_options)
{
}
tx_command::tx_command() : command(requires_options) {}
command::meta_t tx_command::meta() const
{
return
{
"tx",
"manages transifex translations"
};
}
command::meta_t tx_command::meta() const
{
return {"tx", "manages transifex translations"};
}
clipp::group tx_command::do_group()
{
return clipp::group(
clipp::command("tx").set(picked_),
clipp::group tx_command::do_group()
{
return clipp::group(
clipp::command("tx").set(picked_),
(clipp::option("-h", "--help") >> help_)
% ("shows this message"),
(clipp::option("-h", "--help") >> help_) % ("shows this message"),
"get" %
(clipp::command("get").set(mode_, modes::get),
(clipp::option("-k", "--key")
& clipp::value("APIKEY") >> key_)
% "API key",
"get" % (clipp::command("get").set(mode_, modes::get),
(clipp::option("-k", "--key") & clipp::value("APIKEY") >> key_) %
"API key",
(clipp::option("-t", "--team")
& clipp::value("TEAM") >> team_)
% "team name",
(clipp::option("-t", "--team") & clipp::value("TEAM") >> team_) %
"team name",
(clipp::option("-p", "--project")
& clipp::value("PROJECT") >> project_)
% "project name",
(clipp::option("-p", "--project") &
clipp::value("PROJECT") >> project_) %
"project name",
(clipp::option("-u", "--url")
& clipp::value("URL") >> url_)
% "project URL",
(clipp::option("-u", "--url") & clipp::value("URL") >> url_) %
"project URL",
(clipp::option("-m", "--minimum")
& clipp::value("PERCENT").set(min_))
% "minimum translation threshold to download [0-100]",
(clipp::option("-m", "--minimum") &
clipp::value("PERCENT").set(min_)) %
"minimum translation threshold to download [0-100]",
(clipp::option("-f", "--force").call([&]{ force_ = true; }))
% "don't check timestamps, re-download all translation files",
(clipp::option("-f", "--force").call([&] {
force_ = true;
})) %
"don't check timestamps, re-download all translation files",
(clipp::value("path") >> path_)
% "path that will contain the .tx directory"
)
(clipp::value("path") >> path_) %
"path that will contain the .tx directory")
|
|
"build" %
(clipp::command("build").set(mode_, modes::build),
"build" % (clipp::command("build").set(mode_, modes::build),
(clipp::value("source") >> path_)
% "path that contains the translation directories",
(clipp::value("source") >> path_) %
"path that contains the translation directories",
(clipp::value("destination") >> dest_)
% "path that will contain the .qm files"
)
);
}
(clipp::value("destination") >> dest_) %
"path that will contain the .qm files"));
}
void tx_command::convert_cl_to_conf()
{
command::convert_cl_to_conf();
void tx_command::convert_cl_to_conf()
{
command::convert_cl_to_conf();
if (!key_.empty())
common.options.push_back("transifex/key=" + key_);
if (!key_.empty())
common.options.push_back("transifex/key=" + key_);
if (!team_.empty())
common.options.push_back("transifex/team=" + team_);
if (!team_.empty())
common.options.push_back("transifex/team=" + team_);
if (!project_.empty())
common.options.push_back("transifex/project=" + project_);
if (!project_.empty())
common.options.push_back("transifex/project=" + project_);
if (!url_.empty())
common.options.push_back("transifex/url=" + url_);
if (!url_.empty())
common.options.push_back("transifex/url=" + url_);
if (min_ >= 0)
common.options.push_back("transifex/minimum=" + std::to_string(min_));
if (min_ >= 0)
common.options.push_back("transifex/minimum=" + std::to_string(min_));
if (force_)
common.options.push_back("transifex/force=" + std::to_string(*force_));
}
if (force_)
common.options.push_back("transifex/force=" + std::to_string(*force_));
}
int tx_command::do_run()
{
switch (mode_)
{
case modes::get:
do_get();
break;
int tx_command::do_run()
{
switch (mode_) {
case modes::get:
do_get();
break;
case modes::build:
do_build();
break;
case modes::build:
do_build();
break;
case modes::none:
default:
u8cerr << "bad tx mode " << static_cast<int>(mode_) << "\n";
throw bailed();
}
case modes::none:
default:
u8cerr << "bad tx mode " << static_cast<int>(mode_) << "\n";
throw bailed();
}
return 0;
}
return 0;
}
std::string tx_command::do_doc()
{
return
"Some values will be taken from the INI file if not specified.\n"
"\n"
"Commands:\n"
"get\n"
" Initializes a Transifex project in the given directory if\n"
" necessary and pulls all the translation files.\n"
"\n"
"build\n"
" Builds all .qm files. The path can either be the transifex\n"
" project (where .tx is) or the `translations` directory (where the\n"
" individual translation directories are).";
}
std::string tx_command::do_doc()
{
return "Some values will be taken from the INI file if not specified.\n"
"\n"
"Commands:\n"
"get\n"
" Initializes a Transifex project in the given directory if\n"
" necessary and pulls all the translation files.\n"
"\n"
"build\n"
" Builds all .qm files. The path can either be the transifex\n"
" project (where .tx is) or the `translations` directory (where the\n"
" individual translation directories are).";
}
void tx_command::do_get()
{
const url u =
conf().transifex().get("url") + "/" +
conf().transifex().get("team") + "/" +
conf().transifex().get("project");
void tx_command::do_get()
{
const url u = conf().transifex().get("url") + "/" +
conf().transifex().get("team") + "/" +
conf().transifex().get("project");
const std::string key = conf().transifex().get("key");
const std::string key = conf().transifex().get("key");
if (key.empty() && !this_env::get_opt("TX_TOKEN"))
{
u8cout <<
"(no key was in the INI, --key wasn't given and TX_TOKEN env\n"
"variable doesn't exist, this will probably fail)\n\n";
}
if (key.empty() && !this_env::get_opt("TX_TOKEN")) {
u8cout << "(no key was in the INI, --key wasn't given and TX_TOKEN env\n"
"variable doesn't exist, this will probably fail)\n\n";
}
// copy the global context, the tools will modify it
context cxcopy = gcx();
// copy the global context, the tools will modify it
context cxcopy = gcx();
u8cout << "initializing\n";
transifex(transifex::init)
.root(path_)
.run(cxcopy);
u8cout << "initializing\n";
transifex(transifex::init).root(path_).run(cxcopy);
u8cout << "configuring\n";
transifex(transifex::config)
.stdout_level(context::level::info)
.root(path_)
.api_key(key)
.url(u)
.run(cxcopy);
u8cout << "configuring\n";
transifex(transifex::config)
.stdout_level(context::level::info)
.root(path_)
.api_key(key)
.url(u)
.run(cxcopy);
u8cout << "pulling\n";
transifex(transifex::pull)
.stdout_level(context::level::info)
.root(path_)
.api_key(key)
.minimum(conf().transifex().get<int>("minimum"))
.force(conf().transifex().get<bool>("force"))
.run(cxcopy);
}
u8cout << "pulling\n";
transifex(transifex::pull)
.stdout_level(context::level::info)
.root(path_)
.api_key(key)
.minimum(conf().transifex().get<int>("minimum"))
.force(conf().transifex().get<bool>("force"))
.run(cxcopy);
}
void tx_command::do_build()
{
fs::path root = path_;
if (fs::exists(root / ".tx") && fs::exists(root / "translations"))
root = root / "translations";
void tx_command::do_build()
{
fs::path root = path_;
if (fs::exists(root / ".tx") && fs::exists(root / "translations"))
root = root / "translations";
tasks::translations::projects ps(root);
tasks::translations::projects ps(root);
fs::path dest = dest_;
op::create_directories(gcx(), dest, op::unsafe);
fs::path dest = dest_;
op::create_directories(gcx(), dest, op::unsafe);
for (auto&& w : ps.warnings())
u8cerr << w << "\n";
for (auto&& w : ps.warnings())
u8cerr << w << "\n";
thread_pool tp;
thread_pool tp;
for (auto& p : ps.get())
{
for (auto& lg : p.langs)
{
// copy the global context, each thread must have its own
tp.add([&, cxcopy=gcx()]() mutable
{
lrelease()
.project(p.name)
.sources(lg.ts_files)
.out(dest)
.run(cxcopy);
});
}
}
}
for (auto& p : ps.get()) {
for (auto& lg : p.langs) {
// copy the global context, each thread must have its own
tp.add([&, cxcopy = gcx()]() mutable {
lrelease()
.project(p.name)
.sources(lg.ts_files)
.out(dest)
.run(cxcopy);
});
}
}
}
} // namespace
} // namespace mob
+721 -799
View File
File diff suppressed because it is too large Load Diff
+236 -254
View File
File diff suppressed because it is too large Load Diff
+455 -482
View File
File diff suppressed because it is too large Load Diff
+237 -259
View File
File diff suppressed because it is too large Load Diff
+507 -541
View File
File diff suppressed because it is too large Load Diff
+108 -122
View File
@@ -2,154 +2,140 @@
#include "../utility.h"
namespace mob
{
namespace mob {
// a set of environment variables; copy-on-write because this gets copied a lot
//
class env
{
public:
using map = std::map<std::wstring, std::wstring>;
// a set of environment variables; copy-on-write because this gets copied a lot
//
class env {
public:
using map = std::map<std::wstring, std::wstring>;
// used in set(); replaces, appends or prepends to a variable if it already
// exists
//
enum flags
{
replace = 1,
append,
prepend
};
// used in set(); replaces, appends or prepends to a variable if it already
// exists
//
enum flags { replace = 1, append, prepend };
// Visual Studio environment variables for 32-bit
//
static env vs_x86();
// Visual Studio environment variables for 32-bit
//
static env vs_x86();
// Visual Studio environment variables for 64-bit
//
static env vs_x64();
// Visual Studio environment variables for 64-bit
//
static env vs_x64();
// Visual Studio environment variables for the given architecture
//
static env vs(arch a);
// Visual Studio environment variables for the given architecture
//
static env vs(arch a);
// empty set
//
env();
// empty set
//
env();
// handle ref count
//
env(const env& e);
env(env&& e);
env& operator=(const env& e);
env& operator=(env&& e);
// handle ref count
//
env(const env& e);
env(env&& e);
env& operator=(const env& e);
env& operator=(env&& e);
// prepends to PATH
//
env& prepend_path(const fs::path& p);
env& prepend_path(const std::vector<fs::path>& v);
// prepends to PATH
//
env& prepend_path(const fs::path& p);
env& prepend_path(const std::vector<fs::path>& v);
// appends to PATH
//
env& append_path(const fs::path& p);
env& append_path(const std::vector<fs::path>& v);
// appends to PATH
//
env& append_path(const fs::path& p);
env& append_path(const std::vector<fs::path>& v);
// sets k=v
//
env& set(std::string_view k, std::string_view v, flags f = replace);
env& set(std::wstring k, std::wstring v, flags f = replace);
// sets k=v
//
env& set(std::string_view k, std::string_view v, flags f=replace);
env& set(std::wstring k, std::wstring v, flags f=replace);
// returns the variable' value, empty if not found
//
std::string get(std::string_view k) const;
// returns the variable' value, empty if not found
//
std::string get(std::string_view k) const;
// map of variables
//
map get_map() const;
// map of variables
//
map get_map() const;
// passed to CreateProcess() in the process class; returns a pointer to a
// block of utf16 strings, owned by this, created on demand
//
void* get_unicode_pointers() const;
// passed to CreateProcess() in the process class; returns a pointer to a
// block of utf16 strings, owned by this, created on demand
//
void* get_unicode_pointers() const;
private:
// shared between copies
//
struct data {
std::mutex m;
map vars;
private:
// shared between copies
//
struct data
{
std::mutex m;
map vars;
// unicode strings, see get_unicode_pointers()
mutable std::wstring sys;
};
// unicode strings, see get_unicode_pointers()
mutable std::wstring sys;
};
// shared data
std::shared_ptr<data> data_;
// shared data
std::shared_ptr<data> data_;
// whether this instance owns the data, set to true in copy_for_write()
// when the data must be modified
bool own_;
// whether this instance owns the data, set to true in copy_for_write()
// when the data must be modified
bool own_;
// creates the unicode strings
//
void create_sys() const;
// returns a pointer inside the map, null if not found
//
std::wstring* find(std::wstring_view name);
const std::wstring* find(std::wstring_view name) const;
// creates the unicode strings
//
void create_sys() const;
// called by set(), sets the value in the map
//
void set_impl(std::wstring k, std::wstring v, flags f);
// returns a pointer inside the map, null if not found
//
std::wstring* find(std::wstring_view name);
const std::wstring* find(std::wstring_view name) const;
// duplicates the data, sets own_=true
//
void copy_for_write();
// called by set(), sets the value in the map
//
void set_impl(std::wstring k, std::wstring v, flags f);
// called by the various *_path() functions, actually changes the PATH
// value
//
env& change_path(const std::vector<fs::path>& v, flags f);
};
// duplicates the data, sets own_=true
//
void copy_for_write();
// represents mob's environment variables
//
struct this_env {
// sets a variable
//
static void set(const std::string& k, const std::string& v,
env::flags f = env::replace);
// called by the various *_path() functions, actually changes the PATH
// value
//
env& change_path(const std::vector<fs::path>& v, flags f);
};
// changes PATH
//
static void prepend_to_path(const fs::path& p);
static void append_to_path(const fs::path& p);
// returns mob's environment variables
//
static env get();
// represents mob's environment variables
//
struct this_env
{
// sets a variable
//
static void set(
const std::string& k,
const std::string& v,
env::flags f=env::replace);
// returns a specific variable; bails out if it doesn't exist
//
static std::string get(const std::string& k);
// changes PATH
//
static void prepend_to_path(const fs::path& p);
static void append_to_path(const fs::path& p);
// returns a specific variable, or empty if it doesn't exist
//
static std::optional<std::string> get_opt(const std::string& k);
// returns mob's environment variables
//
static env get();
private:
// used by get() and get_opt(), does the actual work
//
static std::optional<std::wstring> get_impl(const std::string& k);
};
// returns a specific variable; bails out if it doesn't exist
//
static std::string get(const std::string& k);
// returns a specific variable, or empty if it doesn't exist
//
static std::optional<std::string> get_opt(const std::string& k);
private:
// used by get() and get_opt(), does the actual work
//
static std::optional<std::wstring> get_impl(const std::string& k);
};
} // namespace
} // namespace mob

Some files were not shown because too many files have changed in this diff Show More