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-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)
|
|
|
|
{
|
|
|
|
if (root)
|
|
|
|
logger = new Logger();
|
|
|
|
}
|
|
|
|
|
|
|
|
Project::~Project() {
|
|
|
|
if (root) {
|
|
|
|
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) {
|
|
|
|
bool success = pair.second.prepare(location, destination);
|
|
|
|
if (success)
|
|
|
|
fine++;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|