in include/poac/subcmd/uninstall.hpp [116:228]
void individual(VS&& argv) {
namespace fs = boost::filesystem;
namespace yaml = io::file::yaml;
namespace resolver = core::resolver;
namespace cli = io::cli;
namespace naming = core::naming;
namespace exception = core::exception;
namespace lock = core::lock;
auto node = yaml::load_config();
std::map<std::string, YAML::Node> deps_node;
if (const auto deps_map = yaml::get<std::map<std::string, YAML::Node>>(node["deps"])) {
deps_node = *deps_map;
check_exist_name(deps_node, argv);
}
else {
throw exception::error("Could not read deps in poac.yml");
}
// create resolved deps
const auto timestamp = yaml::get_timestamp();
resolver::Resolved resolved_deps{};
if (const auto locked_deps = lock::load(timestamp)) {
resolved_deps = *locked_deps;
}
else { // poac.lock does not exist
const resolver::Deps deps = _install::resolve_packages(deps_node);
resolved_deps = resolver::resolve(deps);
}
// create uninstall list
cli::echo();
resolver::Backtracked uninstall_list{};
const auto first = resolved_deps.activated.begin();
const auto last = resolved_deps.activated.end();
for (const auto& v : argv) {
create_uninstall_list(first, last, v, uninstall_list);
}
// Omit package that does not already exist
// confirm
if (!util::argparse::use_rm(argv, "-y", "--yes")) {
for (const auto& [name, dep] : uninstall_list) {
std::cout << name << ": " << dep.version << std::endl;
}
cli::echo();
std::cout << "Are you sure delete above packages? [Y/n] ";
std::string yes_or_no;
std::cin >> yes_or_no;
std::transform(yes_or_no.begin(), yes_or_no.end(), yes_or_no.begin(), ::tolower);
if (!(yes_or_no == "yes" || yes_or_no == "y")) {
std::cout << "canceled." << std::endl;
return;
}
}
// Delete what was added to uninstall_list
cli::echo();
for (const auto& [name, dep] : uninstall_list) {
const auto package_name = naming::to_current(dep.source, name, dep.version);
const auto package_path = io::file::path::current_deps_dir / package_name;
if (io::file::path::validate_dir(package_path)) {
fs::remove_all(package_path);
std::cout << name << " is deleted" << std::endl;
}
else {
std::cout << io::cli::to_red(name + " is not found") << std::endl;
}
}
// lockファイルとymlファイルを書き換える
// もし,uninstall_listと,lockファイルの中身が同一なら,完全にdepsがないということだから,poac.ymlのdepsキーとpoac.lockを消す
if (resolved_deps.backtracked == uninstall_list) {
node.remove("deps");
if (std::ofstream ofs("poac.yml"); ofs) {
ofs << node;
}
else {
throw exception::error("Could not open poac.yml");
}
fs::remove("poac.lock");
}
else {
// uninstall_listに入っていないパッケージのみを書き込む
for (const auto& [name, dep] : uninstall_list) {
// 先に,resolved_deps.activatedから,uninstall_listと同じものを削除する
const auto itr = std::find_if(resolved_deps.activated.begin(), resolved_deps.activated.end(),
[name=name](auto x){ return x.name == name; });
if (itr != resolved_deps.activated.end()) {
resolved_deps.activated.erase(itr);
}
// 同様に,deps_nodeからそのkeyを削除する
if (dep.source == "poac") {
node["deps"].remove(name);
}
else if (dep.source == "github") {
node["deps"].remove("github/" + name);
}
}
if (std::ofstream ofs("poac.yml"); ofs) {
ofs << node;
}
else {
throw exception::error("Could not open poac.yml");
}
_install::create_lock_file(timestamp, resolved_deps.activated);
}
cli::echo();
cli::echo(cli::status_done());
}