99 changed files with 20370 additions and 19031 deletions
-26
View File
@@ -1,26 +0,0 @@
---
# 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
-7
View File
@@ -1,7 +0,0 @@
# 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
+6
View File
@@ -0,0 +1,6 @@
cmake_minimum_required(VERSION 3.16)
project(mob)
add_subdirectory(src)
set_property(DIRECTORY ${PROJECT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT mob)
+9 -30
View File
@@ -1,40 +1,19 @@
$root = $PSScriptRoot
if (!$root) {
$root = "."
$root = "."
}
$installationPath = & $root\third-party\bin\vswhere.exe -products * -nologo -prerelease -latest -property installationPath
if (! $?) {
Write-Error "vswhere returned $LastExitCode"
exit $LastExitCode
}
if (! $installationPath) {
Write-Error "Empty installation path"
exit 1
}
$opts = ""
$opts += " $root\vs\mob.sln"
$opts += " -m"
$opts += " -p:Configuration=Release"
$opts += " -noLogo"
$opts += " -p:UseMultiToolTask=true"
$opts += " -p:EnforceProcessCountAcrossBuilds=true"
$opts += " -clp:ErrorsOnly;Verbosity=minimal"
$vsDevCmd = "$installationPath\Common7\Tools\VsDevCmd.bat"
if (!(Test-Path "$vsDevCmd")) {
Write-Error "VdDevCmd.bat not found at $vsDevCmd"
exit 1
}
& "${env:COMSPEC}" /c "`"$vsDevCmd`" -no_logo -arch=amd64 -host_arch=amd64 && msbuild $opts"
cmake -B build $root | Out-Null
cmake --build $root/build --config Release -- `
"-p:UseMultiToolTask=true" `
"-noLogo" `
"-p:EnforceProcessCountAcrossBuilds=true" `
"-clp:ErrorsOnly;Verbosity=minimal"
if (! $?) {
Write-Error "Build failed"
exit $LastExitCode
}
Copy-Item "$root\build\Release\x64\mob.exe" "$root\mob.exe"
echo "run ``.\mob -d prefix/path build`` to start building"
Copy-Item "$root\build\src\Release\mob.exe" "$root\mob.exe"
Write-Output "run ``.\mob -d prefix/path build`` to start building"
+1 -5
View File
@@ -21,10 +21,6 @@ host =
super = cmake_common modorganizer* githubpp
plugins = check_fnis bsapacker bsa_extractor diagnose_basic installer_* plugin_python preview_base preview_bsa tool_* game_*
[translations]
mo2-translations = organizer
mo2-game-bethesda = game_creation game_enderal game_enderalse game_fallout3 game_fallout4 game_fallout4vr game_falloutNV game_gamebryo game_morrowind game_nehrim game_oblivion game_skyrim game_skyrimse game_skyrimvr game_ttw
[task]
enabled = true
mo_org = ModOrganizer2
@@ -148,10 +144,10 @@ install_pdbs =
install_dlls =
install_loot =
install_plugins =
install_extensions =
install_stylesheets =
install_licenses =
install_pythoncore =
install_translations =
vs =
qt_install =
qt_bin =
+22
View File
@@ -0,0 +1,22 @@
cmake_minimum_required(VERSION 3.16)
file(GLOB_RECURSE source_files *.cpp)
file(GLOB RECURSE header_files *.h)
add_executable(mob ${source_files})
set_target_properties(mob PROPERTIES CXX_STANDARD 20)
target_compile_definitions(mob PUBLIC NOMINMAX)
target_compile_options(mob PUBLIC "/MT")
target_include_directories(mob PUBLIC ${CMAKE_SOURCE_DIR}/third-party/include)
target_link_libraries(mob PUBLIC
wsock32 ws2_32 crypt32 wldap32 dbghelp shlwapi version
optimized ${CMAKE_SOURCE_DIR}/third-party/lib/libcurl.lib
debug ${CMAKE_SOURCE_DIR}/third-party/lib/libcurl-d.lib
optimized ${CMAKE_SOURCE_DIR}/third-party/lib/zlib.lib
debug ${CMAKE_SOURCE_DIR}/third-party/lib/zlibd.lib)
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR}
PREFIX src
FILES ${source_files} ${header_files})
set_property(DIRECTORY ${PROJECT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT mob)
+155 -150
View File
@@ -1,195 +1,200 @@
#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 mob
} // namespace
+63 -45
View File
@@ -1,65 +1,83 @@
#include "pch.h"
#include "../tasks/tasks.h"
#include "commands.h"
#include "../tasks/tasks.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 mob
} // namespace
+372 -319
View File
File diff suppressed because it is too large Load Diff
+479 -423
View File
File diff suppressed because it is too large Load Diff
+229 -191
View File
@@ -1,247 +1,285 @@
#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 mob
} // namespace
+80 -63
View File
@@ -1,83 +1,100 @@
#include "pch.h"
#include "../tasks/task.h"
#include "../tasks/task_manager.h"
#include "../utility/io.h"
#include "commands.h"
#include "../tasks/task_manager.h"
#include "../tasks/task.h"
#include "../utility/io.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;
}
void list_command::dump(const std::vector<task*>& v, std::size_t indent) const
{
for (auto&& t : v) {
if (!t->enabled())
continue;
return 0;
}
u8cout << std::string(indent * 4, ' ') << " - " << join(t->names(), ",")
<< "\n";
void list_command::dump(const std::vector<task*>& v, std::size_t indent) const
{
for (auto&& t : v)
{
if (!t->enabled())
continue;
if (auto* pt = dynamic_cast<parallel_tasks*>(t))
dump(pt->children(), indent + 1);
}
}
u8cout
<< std::string(indent*4, ' ')
<< " - " << join(t->names(), ",")
<< "\n";
void list_command::dump_aliases() const
{
const auto v = task_manager::instance().aliases();
if (v.empty())
return;
if (auto* pt=dynamic_cast<parallel_tasks*>(t))
dump(pt->children(), indent + 1);
}
}
for (auto&& [k, patterns] : v)
u8cout << " - " << k << ": " << join(patterns, ", ") << "\n";
}
void list_command::dump_aliases() const
{
const auto v = task_manager::instance().aliases();
if (v.empty())
return;
} // namespace mob
for (auto&& [k, patterns] : v)
u8cout << " - " << k << ": " << join(patterns, ", ") << "\n";
}
} // namespace
+403 -358
View File
File diff suppressed because it is too large Load Diff
+587 -525
View File
File diff suppressed because it is too large Load Diff
+166 -141
View File
@@ -1,188 +1,213 @@
#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 mob
} // namespace
+799 -739
View File
File diff suppressed because it is too large Load Diff
+253 -251
View File
File diff suppressed because it is too large Load Diff
+482 -455
View File
File diff suppressed because it is too large Load Diff
+259 -237
View File
File diff suppressed because it is too large Load Diff
+536 -502
View File
File diff suppressed because it is too large Load Diff

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