<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include <algorithm>
#include <boost/filesystem.hpp>
#include <iostream>
#include <map>

#include "color.hh"
#include "install_packages.hh"
#include "parse_packages.hh"

using namespace std;
static void calculate_dependency(
    const string& p,
    vector<pair<string, bool> >& pac,
    const map<string, pair<string, vector<string> > >& pacstash)
{
    if (p.empty()) return;
    auto itr = pacstash.find(p);
    if (itr == pacstash.end()) {
        cerr << RED("Error:")
             << " Package not recognized: " << p << endl;
        exit(EXIT_FAILURE);
    }
    for (auto& a : itr->second.second) {
        if (find_if(begin(pac), end(pac), [&a](pair<string, bool>& p) {
                return a == p.first;
            }) == end(pac)) {
            pac.emplace_back(a, false);
            calculate_dependency(a, pac, pacstash);
        }
    }
}
static void calculate_dependencies(
    vector<pair<string, bool> >& pac,
    const map<string, pair<string, vector<string> > >& pacstash)
{
    for (auto& p : pac) {
        calculate_dependency(p.first, pac, pacstash);
    }
}

void install_packages(const boost::filesystem::path& package_list,
                      int num_packages, const char* const* packages) {
    using namespace boost::filesystem;

    // ensure valid path to packages
    {
        path p;
        try {
            p = packages[-2];
        } catch (filesystem_error&) {
            goto filesystemerr;
        }
        if (not is_regular_file(p)) {
        filesystemerr:
            cerr << RED("Error:") << " Package list ("
                 << package_list.string() << ") is not a valid file"
                 << endl;
            exit(EXIT_FAILURE);
        }
    }

    map<string, pair<string, vector<string> > > pacstash =
        parse_packages(package_list.c_str());

    const path cur = current_path() / "plugins";
    auto n = num_packages;
    auto p = packages;
    auto should_throw = false;
    for (; n; --n, ++p) {
        path comb = cur / *p;
        if (exists(comb)) {
            cerr << BOLD("Warning:")
                 << " Package you specified to install (" << *p
                 << ") is already installed." << endl
                 << "  Will remove and reinstall!" << endl;
        }
        if (pacstash.find(*p) == pacstash.end()) {
            cerr << RED("Error:")
                 << " Package you specified to install (" << *p
                 << ") is not a key in the package list you gave ("
                 << package_list.string() << ")." << endl;
            should_throw = true;
        }
    }

    if (should_throw) {
        cerr << RED("Error:") << " Some packages aren't registered "
                                 "so won't install any specified."
             << endl;
        exit(EXIT_FAILURE);
    }

    vector<pair<string, bool> > pac;
    pac.reserve(num_packages);
    for (auto i = packages; i != packages + num_packages; ++i) {
        pac.emplace_back(*i, true);
    }
    calculate_dependencies(pac, pacstash);
    sort(begin(pac), end(pac));

    cout << BOLD("Packages to install (" << pac.size() << "):");
    for (auto& s : pac) {
        cout << "  " << s.first;
    }
    cout << endl << BOLD("Continue with installation? [Y,n] ");

    char c = getchar();
    if (not (c == 'Y' or c == 'y' or c == '\n')) {
        exit(EXIT_FAILURE);
    }
    cout << endl;
    for (auto& pack : pac) {
        chdir(cur.c_str());<commit_msg>Comment things<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include <algorithm>
#include <boost/filesystem.hpp>
#include <iostream>
#include <map>

#include "color.hh"
#include "install_packages.hh"
#include "parse_packages.hh"

using namespace std;
static void calculate_dependency(
    const string& p,
    vector<pair<string, bool> >& pac,
    const map<string, pair<string, vector<string> > >& pacstash)
{
    if (p.empty()) return;
    auto itr = pacstash.find(p);
    if (itr == pacstash.end()) {
        cerr << RED("Error:")
             << " Package not recognized: " << p << endl;
        exit(EXIT_FAILURE);
    }
    for (auto& a : itr->second.second) {
        if (find_if(begin(pac), end(pac), [&a](pair<string, bool>& p) {
                return a == p.first;
            }) == end(pac)) {
            pac.emplace_back(a, false);
            calculate_dependency(a, pac, pacstash);
        }
    }
}
static void calculate_dependencies(
    vector<pair<string, bool> >& pac,
    const map<string, pair<string, vector<string> > >& pacstash)
{
    for (auto& p : pac) {
        calculate_dependency(p.first, pac, pacstash);
    }
}

void install_packages(const boost::filesystem::path& package_list,
                      int num_packages, const char* const* packages) {
    using namespace boost::filesystem;

    // ensure valid path to packages
    {
        path p;
        try {
            p = packages[-2];
        } catch (filesystem_error&) {
            goto filesystemerr;
        }
        if (not is_regular_file(p)) {
        filesystemerr:
            cerr << RED("Error:") << " Package list ("
                 << package_list.string() << ") is not a valid file"
                 << endl;
            exit(EXIT_FAILURE);
        }
    }

    map<string, pair<string, vector<string> > > pacstash =
        parse_packages(package_list.c_str());

    const path cur = current_path() / "plugins";
    auto n = num_packages;
    auto p = packages;
    auto should_throw = false;
    for (; n; --n, ++p) {
        path comb = cur / *p;
        if (exists(comb)) {
            cerr << BOLD("Warning:")
                 << " Package you specified to install (" << *p
                 << ") is already installed." << endl
                 << "  Will remove and reinstall!" << endl;
        }
        if (pacstash.find(*p) == pacstash.end()) {
            cerr << RED("Error:")
                 << " Package you specified to install (" << *p
                 << ") is not a key in the package list you gave ("
                 << package_list.string() << ")." << endl;
            should_throw = true;
        }
    }

    if (should_throw) {
        cerr << RED("Error:") << " Some packages aren't registered "
                                 "so won't install any specified."
             << endl;
        exit(EXIT_FAILURE);
    }

    vector<pair<string, bool> > pac;
    pac.reserve(num_packages);
    for (auto i = packages; i != packages + num_packages; ++i) {
        // packages explicitly asked for are deleted and recloned
        pac.emplace_back(*i, true);
    }
    // packages pulled in as dependencies are just updated
    calculate_dependencies(pac, pacstash);
    // alphabetize so output is pretty
    sort(begin(pac), end(pac));

    cout << BOLD("Packages to install/update (" << pac.size() << "):");
    for (auto& s : pac) {
        cout << "  " << s.first;
    }
    cout << endl << BOLD("Continue with installation? [Y,n] ");

    char c = getchar();
    if (not (c == 'Y' or c == 'y' or c == '\n')) {
        exit(EXIT_FAILURE);
    }
    cout << endl;
    for (auto& pack : pac) {
        chdir(cur.c_str());
{'fraction_non_alphanumeric': 0.14627304301362543, 'fraction_numerical': 0.0013358268768367619, 'mean_word_length': 2.0373225152129817, 'pattern_counts': {'":': 0, '<': 179, '<?xml version=': 0, '>': 45, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5074988', 'n_tokens_mistral': 2334, 'n_tokens_neox': 2275, 'n_words': 631}