mason/src/project.cpp

238 lines
5.6 KiB
C++
Raw Normal View History

2023-08-30 20:54:59 +00:00
#include "project.h"
#include <string_view>
#include <exception>
2023-08-31 20:06:02 +00:00
using json = nlohmann::json;
2023-08-30 20:54:59 +00:00
constexpr std::string_view entry("mason.json");
2023-08-31 20:06:02 +00:00
std::map<std::string, Dependency::Type> types({
{"simple", Dependency::Type::simple},
{"none", Dependency::Type::simple},
{"mason", Dependency::Type::mason},
{"auto", Dependency::Type::automatic},
{"automatic", Dependency::Type::automatic}
});
2023-09-01 21:39:24 +00:00
Logger* Project::logger = nullptr;
Project::Project(const std::filesystem::path& location, const std::filesystem::path& destination):
2023-09-17 19:34:00 +00:00
parent(nullptr),
2023-08-30 20:54:59 +00:00
location(location),
2023-09-01 21:39:24 +00:00
destination(destination),
state(State::unknown),
2023-08-31 20:06:02 +00:00
name(),
2023-09-01 21:39:24 +00:00
dependencies(),
root(logger == nullptr)
{
2023-09-03 00:53:36 +00:00
if (root) {
curl_global_init(CURL_GLOBAL_ALL);
logger = new Logger(Logger::Severity::debug);
}
2023-09-01 21:39:24 +00:00
}
2023-09-17 19:34:00 +00:00
Project::Project(const std::filesystem::path& location, const std::filesystem::path& destination, Project* parent):
parent(parent),
location(location),
destination(destination),
state(State::unknown),
name(),
dependencies(),
root(false) {}
2023-09-01 21:39:24 +00:00
Project::~Project() {
if (root) {
2023-09-03 00:53:36 +00:00
curl_global_cleanup();
2023-09-01 21:39:24 +00:00
delete logger;
logger = nullptr;
}
}
2023-08-30 20:54:59 +00:00
bool Project::read() {
2023-09-01 21:39:24 +00:00
if (state == State::read)
2023-08-30 20:54:59 +00:00
return true;
std::filesystem::path entryPointPath;
try {
2023-09-01 21:39:24 +00:00
location = std::filesystem::canonical(location);
entryPointPath = location / entry;
2023-08-30 20:54:59 +00:00
} catch (const std::exception& e) {
2023-09-01 21:39:24 +00:00
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;
2023-08-30 20:54:59 +00:00
return false;
}
std::ifstream file(entryPointPath);
if (!file.is_open()) {
2023-09-01 21:39:24 +00:00
fatal("couldn't open " + entryPointPath.string());
state = State::error;
2023-08-30 20:54:59 +00:00
return false;
}
2023-08-31 20:06:02 +00:00
json data;
try {
data = json::parse(file);
} catch (const json::exception& e) {
2023-09-01 21:39:24 +00:00
fatal(e.what());
state = State::error;
2023-08-31 20:06:02 +00:00
return false;
}
2023-08-30 20:54:59 +00:00
try {
2023-08-31 20:06:02 +00:00
parse(data);
2023-08-30 20:54:59 +00:00
} catch (const std::exception& e) {
2023-09-01 21:39:24 +00:00
fatal(e.what());
state = State::error;
2023-08-30 20:54:59 +00:00
return false;
}
return true;
}
2023-08-31 20:06:02 +00:00
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<std::string> name = std::nullopt;
itr = entry.find("name");
if (itr != entry.end() && itr->is_string())
name = *itr;
std::optional<std::string> 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<std::string, Dependency::Type>::const_iterator titr = types.find(*itr);
if (titr != types.end())
type = titr->second;
}
dependencies.emplace(url, Dependency{url, type, name, version});
}
2023-09-01 21:39:24 +00:00
void Project::discover() {
int fine = 0;
for (std::pair<const std::string, Dependency>& pair : dependencies) {
2023-09-17 19:34:00 +00:00
Dependency& dep = pair.second;
bool success = dep.prepare(location, destination);
if (success) {
switch (dep.getType()) {
case Dependency::Type::mason:
break;
case Dependency::Type::simple:
break;
default:
break;
}
2023-09-01 21:39:24 +00:00
fine++;
2023-09-17 19:34:00 +00:00
}
2023-09-01 21:39:24 +00:00
}
}
2023-08-31 20:06:02 +00:00
uint32_t Project::dependenciesCount() const {
return dependencies.size();
}
2023-09-01 21:39:24 +00:00
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);
}
2023-09-03 00:53:36 +00:00
void Project::minor(const std::string& message) {
log(Logger::Severity::minor, message);
}
void Project::major(const std::string& message) {
log(Logger::Severity::major, message);
}
2023-09-01 21:39:24 +00:00
void Project::error(const std::string& message) {
log(Logger::Severity::error, message);
}
void Project::warn(const std::string& message) {
log(Logger::Severity::warning, message);
}
2023-08-31 20:06:02 +00:00
2023-09-01 21:39:24 +00:00
void Project::fatal(const std::string& message) {
log(Logger::Severity::fatal, message);
2023-08-30 20:54:59 +00:00
}
2023-09-01 21:39:24 +00:00
void Project::printLog() {
if (logger != nullptr)
logger->printLog();
2023-08-30 20:54:59 +00:00
}
2023-09-01 21:39:24 +00:00
Project::State Project::getStatus() const {
return state;
2023-08-30 20:54:59 +00:00
}
std::string Project::getName() const {
return name;
}