tx command

added tx binary
This commit is contained in:
isanae
2020-07-11 17:16:47 -04:00
parent 81e3bd19b5
commit eca4a2d82e
10 changed files with 341 additions and 24 deletions
+7
View File
@@ -48,8 +48,15 @@ msbuild = msbuild.exe
nuget = nuget.exe
vswhere = vswhere.exe
nasm = nasm.exe
tx = tx.py37-x64.exe
vcvars =
[transifex]
enabled = true
key =
url = https://www.transifex.com/mod-organizer-2-team/mod-organizer-2/
minimum = 60
[prebuilt]
boost = true
lz4 = true
+111 -10
View File
@@ -1103,18 +1103,19 @@ std::string git_command::do_doc()
"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"
" 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"
" 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.";
" Toggles the --assume-changed status of all .ts files in all repos.";
}
void git_command::do_set_remotes()
@@ -1325,6 +1326,10 @@ std::string inis_command::do_doc()
}
tx_command::tx_command()
: command(requires_options)
{
}
command::meta_t tx_command::meta() const
{
@@ -1341,18 +1346,114 @@ clipp::group tx_command::do_group()
clipp::command("tx").set(picked_),
(clipp::option("-h", "--help") >> help_)
% ("shows this message")
% ("shows this message"),
"get" %
(clipp::command("get").set(mode_, modes::get),
(clipp::option("-m", "--minimum")
& clipp::value("PERCENT") >> min_)
% "minimum translation threshold to download [0-100]",
(clipp::option("-k", "--key")
& clipp::value("APIKEY") >> key_)
% "API key",
(clipp::option("-f", "--force").set(force_)
% "don't check timestamps, re-download all translation files"),
(clipp::option("-u", "--url")
& clipp::value("URL") >> url_)
% "project URL",
(clipp::value("path") >> path_)
% "path that will contain the .tx directory"
)
);
}
int tx_command::do_run()
{
return prepare_options(true);
switch (mode_)
{
case modes::get:
do_get();
break;
case modes::none:
default:
u8cerr << "bad tx mode " << static_cast<int>(mode_) << "\n";
throw bailed();
}
return 0;
}
std::string tx_command::do_doc()
{
return "";
return
"Values for --key, --minimum and --url will be taken from the INI\n"
"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.";
}
void tx_command::do_get()
{
if (min_ < 0)
{
const auto s = conf::get_global("transifex", "minimum");
try
{
min_ = std::stoi(s);
}
catch(std::exception&)
{
gcx().bail_out(context::generic,
"bad transifex minimum percentage '{}'", s);
}
}
if (key_.empty())
key_ = conf::get_global("transifex", "key");
if (url_.empty())
url_ = conf::get_global("transifex", "url");
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";
}
context cxcopy = gcx();
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(url_)
.run(cxcopy);
u8cout << "pulling\n";
transifex(transifex::pull)
.stdout_level(context::level::info)
.root(path_)
.api_key(key_)
.minimum(min_)
.force(force_)
.run(cxcopy);
}
} // namespace
+17
View File
@@ -281,12 +281,29 @@ protected:
class tx_command : public command
{
public:
tx_command();
meta_t meta() const override;
protected:
clipp::group do_group() override;
int do_run() override;
std::string do_doc() override;
private:
enum class modes
{
none = 0,
get
};
modes mode_ = modes::none;
int min_ = -1;
std::string key_;
std::string url_;
bool force_ = false;
std::string path_;
void do_get();
};
} // namespace
+4 -2
View File
@@ -29,10 +29,12 @@ void touch(const context& cx, const fs::path& p)
do_touch(cx ,p);
}
void create_directories(const context& cx, const fs::path& p)
void create_directories(const context& cx, const fs::path& p, flags f)
{
cx.trace(context::fs, "creating dir {}", p);
check(cx, p);
if (!is_set(f, unsafe))
check(cx, p);
if (!conf::dry())
do_create_directories(cx, p);
+1 -1
View File
@@ -22,7 +22,7 @@ MOB_ENUM_OPERATORS(flags);
void touch(const context& cx, const fs::path& p);
void create_directories(
const context& cx, const fs::path& p);
const context& cx, const fs::path& p, flags f=noflags);
void delete_directory(
const context& cx, const fs::path& p, flags f=noflags);
+25 -8
View File
@@ -257,6 +257,7 @@ process::process() :
cx_(&gcx()), unicode_(false), chcp_(-1), flags_(process::noflags),
stdout_(context::level::trace), stderr_(context::level::error), code_(0)
{
success_.insert(0);
}
process::~process()
@@ -398,6 +399,12 @@ process::flags_t process::flags() const
return flags_;
}
process& process::success_exit_codes(std::set<int> v)
{
success_ = v;
return *this;
}
process& process::env(const mob::env& e)
{
env_ = e;
@@ -663,7 +670,9 @@ void process::read_pipe(
return;
}
cx_->log_string(f.r, f.lv, f.line);
if (!is_set(flags_, ignore_output_on_success))
cx_->log_string(f.r, f.lv, f.line);
logs_[f.lv].emplace_back(std::move(line));
});
@@ -706,16 +715,23 @@ void process::on_completed()
}
// success
if (code_ == 0)
if (success_.contains(static_cast<int>(code_)))
{
const bool ignore_output = is_set(flags_, ignore_output_on_success);
const auto& warnings = logs_[context::level::warning];
const auto& errors = logs_[context::level::error];
if (!warnings.empty() || !errors.empty())
if (ignore_output || (warnings.empty() && errors.empty()))
{
cx_->trace(context::cmd,
"process exit code is {} (considered success)", code_);
}
else
{
cx_->warning(
context::cmd,
"process exit code is 0, but stderr had something");
"process exit code is {} (considered success), "
"but stderr had something", code_);
cx_->warning(context::cmd, "process was: {}", make_cmd());
cx_->warning(context::cmd, "stderr:");
@@ -726,10 +742,6 @@ void process::on_completed()
for (auto&& line : errors)
cx_->warning(context::std_err, " {}", line);
}
else
{
cx_->trace(context::cmd, "process exit code is 0");
}
return;
}
@@ -940,6 +952,11 @@ std::string process::arg_to_string(const url& u, arg_flags f)
return u.string();
}
std::string process::arg_to_string(int i, arg_flags)
{
return std::to_string(i);
}
encoded_buffer::encoded_buffer(encodings e, std::string bytes)
: e_(e), bytes_(std::move(bytes)), last_(0)
+8 -3
View File
@@ -164,9 +164,10 @@ class process
public:
enum flags_t
{
noflags = 0x00,
allow_failure = 0x01,
terminate_on_interrupt = 0x02
noflags = 0x00,
allow_failure = 0x01,
terminate_on_interrupt = 0x02,
ignore_output_on_success = 0x04
};
enum arg_flags
@@ -261,6 +262,8 @@ public:
process& flags(flags_t f);
flags_t flags() const;
process& success_exit_codes(std::set<int> v);
template <class T, class=std::enable_if_t<!std::is_same_v<T, arg_flags>>>
process& arg(const T& value, arg_flags f=noargflags)
{
@@ -338,6 +341,7 @@ private:
bool unicode_;
int chcp_;
flags_t flags_;
std::set<int> success_;
stream stdout_;
stream stderr_;
mob::env env_;
@@ -371,6 +375,7 @@ private:
std::string arg_to_string(const std::string& s, arg_flags f);
std::string arg_to_string(const fs::path& p, arg_flags f);
std::string arg_to_string(const url& u, arg_flags f);
std::string arg_to_string(int i, arg_flags f);
};
+128
View File
@@ -256,4 +256,132 @@ void pip_install::do_run()
execute_and_join();
}
transifex::transifex(ops o) :
basic_process_runner("transifex"), op_(o),
stdout_(context::level::trace), min_(100), force_(false)
{
}
fs::path transifex::binary()
{
return conf::tool_by_name("tx");
}
transifex& transifex::root(const fs::path& p)
{
root_ = p;
return *this;
}
transifex& transifex::api_key(const std::string& key)
{
key_ = key;
return *this;
}
transifex& transifex::url(const mob::url& u)
{
url_ = u;
return *this;
}
transifex& transifex::minimum(int percent)
{
min_ = percent;
return *this;
}
transifex& transifex::stdout_level(context::level lv)
{
stdout_ = lv;
return *this;
}
transifex& transifex::force(bool b)
{
force_ = b;
return *this;
}
void transifex::do_run()
{
switch (op_)
{
case init:
do_init();
break;
case config:
do_config();
break;
case pull:
do_pull();
break;
default:
cx().bail_out(context::generic, "tx unknown op {}", op_);
}
}
void transifex::do_init()
{
op::create_directories(cx(), root_, op::unsafe);
// exit code is 2 when the directory already contains a .tx
process_ = process()
.binary(binary())
.success_exit_codes({0, 2})
.flags(process::ignore_output_on_success)
.arg("init")
.arg("--no-interactive")
.cwd(root_);
execute_and_join();
}
void transifex::do_config()
{
if (url_.empty())
cx().bail_out(context::generic, "missing transifex url");
op::create_directories(cx(), root_, op::unsafe);
process_ = process()
.binary(binary())
.stdout_level(stdout_)
.arg("config")
.arg("mapping-remote")
.arg(url_)
.env(this_env::get()
.set("TX_TOKEN", key_))
.cwd(root_);
execute_and_join();
}
void transifex::do_pull()
{
op::create_directories(cx(), root_, op::unsafe);
process_ = process()
.binary(binary())
.stdout_level(stdout_)
.arg("pull")
.arg("--all")
.arg("--parallel")
.arg("--no-interactive")
.arg("--minimum-perc", min_)
.env(this_env::get()
.set("TX_TOKEN", key_))
.cwd(root_);
if (force_)
process_.arg("--force");
execute_and_join();
}
} // namespace
+40
View File
@@ -558,4 +558,44 @@ private:
fs::path file_;
};
class transifex : public basic_process_runner
{
public:
enum ops
{
init = 1,
config,
pull
};
static fs::path binary();
transifex(ops op);
transifex& root(const fs::path& p);
transifex& api_key(const std::string& key);
transifex& url(const mob::url& u);
transifex& minimum(int percent);
transifex& stdout_level(context::level lv);
transifex& force(bool b);
protected:
void do_run() override;
private:
ops op_;
context::level stdout_;
fs::path root_;
std::string key_;
mob::url url_;
int min_;
bool force_;
void do_init();
void do_config();
void do_pull();
};
} // namespace
BIN
View File
Binary file not shown.