mirror of
https://github.com/ModOrganizer2/mob.git
synced 2026-07-27 14:07:05 -07:00
184 lines
3.6 KiB
C++
184 lines
3.6 KiB
C++
#include "pch.h"
|
|
#include "tools.h"
|
|
#include "../core/process.h"
|
|
#include "../tasks/tasks.h"
|
|
|
|
namespace mob
|
|
{
|
|
|
|
python::python()
|
|
: basic_process_runner("python")
|
|
{
|
|
}
|
|
|
|
python& python::root(const fs::path& p)
|
|
{
|
|
root_ = p;
|
|
return *this;
|
|
}
|
|
|
|
python& python::arg(const std::string& s)
|
|
{
|
|
args_.push_back(s);
|
|
return *this;
|
|
}
|
|
|
|
void python::do_run()
|
|
{
|
|
// python is a bit finicky for utf8, so:
|
|
// 1) chcp changes the codepage to utf8
|
|
// 2) `-X utf8` and the PYTHONUTF8 environment variable are set, which
|
|
// is probably redundant
|
|
|
|
auto p = process()
|
|
.binary(tasks::python::python_exe())
|
|
.chcp(65001)
|
|
.stdout_encoding(encodings::utf8)
|
|
.stderr_encoding(encodings::utf8)
|
|
.stderr_filter([&](process::filter& f)
|
|
{
|
|
// filter out crap from setuptools
|
|
if (f.line.find("zip_safe flag not set") != std::string::npos)
|
|
f.lv = context::level::trace;
|
|
else if (f.line.find("module references __file__") != std::string::npos)
|
|
f.lv = context::level::trace;
|
|
})
|
|
.arg("-X", "utf8"); // forces utf8
|
|
|
|
for (auto&& a : args_)
|
|
p.arg(a);
|
|
|
|
p
|
|
.cwd(root_)
|
|
.env(this_env::get().set("PYTHONUTF8", "1")); // forces utf8
|
|
|
|
execute_and_join(p);
|
|
}
|
|
|
|
|
|
pip::pip(ops op)
|
|
: basic_process_runner("pip"), op_(op)
|
|
{
|
|
}
|
|
|
|
pip& pip::package(const std::string& s)
|
|
{
|
|
package_ = s;
|
|
return *this;
|
|
}
|
|
|
|
pip& pip::version(const std::string& s)
|
|
{
|
|
version_ = s;
|
|
return *this;
|
|
}
|
|
|
|
pip& pip::file(const fs::path& p)
|
|
{
|
|
file_ = p;
|
|
return *this;
|
|
}
|
|
|
|
void pip::do_run()
|
|
{
|
|
switch (op_)
|
|
{
|
|
case ensure:
|
|
do_ensure();
|
|
break;
|
|
|
|
case install:
|
|
do_install();
|
|
break;
|
|
|
|
case download:
|
|
do_download();
|
|
break;
|
|
|
|
default:
|
|
cx().bail_out(context::generic, "pip unknown op {}", op_);
|
|
}
|
|
}
|
|
|
|
void pip::do_ensure()
|
|
{
|
|
// ensure
|
|
execute_and_join(process()
|
|
.stderr_filter([](auto&& f)
|
|
{
|
|
// this spits out two warnings about not being on PATH and suggests
|
|
// to add --no-warn-script-location, but that's not actually a valid
|
|
// parameter for `ensurepip` and it fails, unlike the `install`
|
|
// commands below
|
|
//
|
|
// so just filter it out
|
|
|
|
if (f.line.find("which is not on PATH") != std::string::npos)
|
|
f.lv = context::level::debug;
|
|
else if (f.line.find("Consider adding this") != std::string::npos)
|
|
f.lv = context::level::debug;
|
|
})
|
|
.binary(tasks::python::python_exe())
|
|
.arg("-m", "ensurepip"));
|
|
|
|
|
|
// upgrade
|
|
execute_and_join(process()
|
|
.binary(tasks::python::python_exe())
|
|
.arg("-m pip")
|
|
.arg("install")
|
|
.arg("--no-warn-script-location")
|
|
.arg("--upgrade pip"));
|
|
|
|
|
|
// ssl errors while downloading through python without certifi
|
|
execute_and_join(process()
|
|
.binary(tasks::python::python_exe())
|
|
.arg("-m pip")
|
|
.arg("install")
|
|
.arg("--no-warn-script-location")
|
|
.arg("certifi"));
|
|
}
|
|
|
|
void pip::do_install()
|
|
{
|
|
auto p = process()
|
|
.binary(tasks::python::python_exe())
|
|
.chcp(65001)
|
|
.stdout_encoding(encodings::utf8)
|
|
.stderr_encoding(encodings::utf8)
|
|
.arg("-X", "utf8")
|
|
.arg("-m", "pip")
|
|
.arg("install")
|
|
.arg("--no-warn-script-location")
|
|
.arg("--disable-pip-version-check");
|
|
|
|
if (!package_.empty())
|
|
p.arg(package_ + "==" + version_);
|
|
else if (!file_.empty())
|
|
p.arg(file_);
|
|
|
|
p.env(this_env::get().set("PYTHONUTF8", "1"));
|
|
|
|
execute_and_join(p);
|
|
}
|
|
|
|
void pip::do_download()
|
|
{
|
|
execute_and_join(process()
|
|
.binary(tasks::python::python_exe())
|
|
.chcp(65001)
|
|
.stdout_encoding(encodings::utf8)
|
|
.stderr_encoding(encodings::utf8)
|
|
.arg("-X", "utf8")
|
|
.arg("-m", "pip")
|
|
.arg("download")
|
|
.arg("--no-binary=:all:")
|
|
.arg("--no-deps")
|
|
.arg("-d", conf().path().cache())
|
|
.arg(package_ + "==" + version_)
|
|
.env(this_env::get().set("PYTHONUTF8", "1")));
|
|
}
|
|
|
|
} // namespace
|