#include "project.h" #include #include using json = nlohmann::json; constexpr std::string_view entry("mason.json"); std::map types({ {"simple", Dependency::Type::simple}, {"none", Dependency::Type::simple}, {"mason", Dependency::Type::mason}, {"auto", Dependency::Type::automatic}, {"automatic", Dependency::Type::automatic} }); Logger* Project::logger = nullptr; Project::Project(const std::filesystem::path& location, const std::filesystem::path& destination): location(location), destination(destination), state(State::unknown), name(), dependencies(), root(logger == nullptr) { if (root) { curl_global_init(CURL_GLOBAL_ALL); logger = new Logger(Logger::Severity::debug); } } Project::~Project() { if (root) { curl_global_cleanup(); delete logger; logger = nullptr; } } bool Project::read() { if (state == State::read) return true; std::filesystem::path entryPointPath; try { location = std::filesystem::canonical(location); entryPointPath = location / entry; } catch (const std::exception& e) { fatal(e.what()); state = State::error; return false; } try { std::filesystem::create_directories(destination); destination = std::filesystem::canonical(destination); } catch (const std::exception& e) { fatal(e.what()); state = State::error; return false; } std::ifstream file(entryPointPath); if (!file.is_open()) { fatal("couldn't open " + entryPointPath.string()); state = State::error; return false; } json data; try { data = json::parse(file); } catch (const json::exception& e) { fatal(e.what()); state = State::error; return false; } try { parse(data); } catch (const std::exception& e) { fatal(e.what()); state = State::error; return false; } return true; } void Project::parse(const json& data) { const json& nm = data.at("name"); if (!nm.is_string()) throw 1; name = nm; const json& dpd = data.at("dependencies"); if (!dpd.is_array()) throw 1; for (const json& dep : dpd) { switch (dep.type()) { case json::value_t::string: createDepencencyFromString(dep); break; case json::value_t::object: createDepencencyFromObject(dep); break; default: throw 1; } } } void Project::createDepencencyFromString(const std::string& entry) { dependencies.emplace(entry, entry); } void Project::createDepencencyFromObject(const nlohmann::json& entry) { std::string url; json::const_iterator itr = entry.find("url"); if (itr == entry.end()) { itr = entry.find("path"); if (itr == entry.end()) throw 1; } if (!itr->is_string()) throw 1; url = *itr; std::optional name = std::nullopt; itr = entry.find("name"); if (itr != entry.end() && itr->is_string()) name = *itr; std::optional version = std::nullopt; itr = entry.find("version"); if (itr != entry.end() && itr->is_string()) version = *itr; Dependency::Type type = Dependency::Type::automatic; itr = entry.find("type"); if (itr != entry.end() && itr->is_string()) { std::map::const_iterator titr = types.find(*itr); if (titr != types.end()) type = titr->second; } dependencies.emplace(url, Dependency{url, type, name, version}); } void Project::discover() { int fine = 0; for (std::pair& pair : dependencies) { bool success = pair.second.prepare(location, destination); if (success) fine++; } } uint32_t Project::dependenciesCount() const { return dependencies.size(); } void Project::log(Logger::Severity severity, const std::string& message) { if (logger != nullptr) logger->log(severity, message); } void Project::info(const std::string& message) { log(Logger::Severity::info, message); } void Project::debug(const std::string& message) { log(Logger::Severity::debug, message); } void Project::minor(const std::string& message) { log(Logger::Severity::minor, message); } void Project::major(const std::string& message) { log(Logger::Severity::major, message); } void Project::error(const std::string& message) { log(Logger::Severity::error, message); } void Project::warn(const std::string& message) { log(Logger::Severity::warning, message); } void Project::fatal(const std::string& message) { log(Logger::Severity::fatal, message); } void Project::printLog() { if (logger != nullptr) logger->printLog(); } Project::State Project::getStatus() const { return state; } std::string Project::getName() const { return name; }