void individual()

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());
        }