libraries directory

This commit is contained in:
Blue 2023-09-29 18:09:09 -03:00
parent 2b913d1d42
commit 0fa8ba6918
Signed by: blue
GPG key ID: 9B203B252A63EE38
7 changed files with 268 additions and 75 deletions

View file

@ -13,6 +13,13 @@ constexpr std::array<std::string_view, Component::done + 1> stringStates {
"done"
};
constexpr std::array<std::string_view, Component::unknown + 1> stringTypes {
"file",
"directory",
"mason",
"unknown"
};
Component::Component(
const std::filesystem::path& path,
const std::weak_ptr<Collection>& collection,
@ -23,7 +30,7 @@ Component::Component(
type(unknown),
collection(collection),
location(path),
scenario(std::nullopt)
manifest(std::nullopt)
{}
void Component::read() {
@ -56,65 +63,73 @@ void Component::tryReadingBuildScenarios() {
}
bool Component::readAsMason() {
std::filesystem::path masonScenarion = location/masonJSON;
std::filesystem::path masonManifest = location/masonJSON;
try {
std::ifstream file(masonScenarion);
std::ifstream file(masonManifest);
if (file.is_open())
scenario = nlohmann::json::parse(file);
manifest = nlohmann::json::parse(file);
else
minor("Couldn't open " + masonScenarion.string());
minor("Couldn't open " + masonManifest.string());
} catch (const nlohmann::json::exception& e) {
major("Couldn't parse " + masonScenarion.string());
major("Couldn't parse " + masonManifest.string());
}
if (scenario.has_value()) {
const nlohmann::json& sc = scenario.value();
if (!sc.is_object())
return errorScenario(masonScenarion.string() + " is unexpected root type");
if (manifest.has_value()) {
const nlohmann::json& mnfst = manifest.value();
if (!mnfst.is_object())
return errorScenario(masonManifest.string() + " is unexpected root type");
nlohmann::json::const_iterator itr = sc.find(dependencies);
if (itr == sc.end()) {
info(masonScenarion.string() + " doesn't have dependencies");
nlohmann::json::const_iterator itr = mnfst.find(dependencies);
if (itr == mnfst.end()) {
info(masonManifest.string() + " doesn't have dependencies");
} else {
const nlohmann::json& deps = *itr;
if (!deps.is_array())
return errorScenario(masonScenarion.string() + " dependencies are not organized as an array");
for (const nlohmann::json& dep : deps) {
std::shared_ptr<Collection> col = collection.lock();
switch (dep.type()) {
case nlohmann::json::value_t::string:
col->addSource(dep);
break;
case nlohmann::json::value_t::object: {
nlohmann::json::const_iterator ditr = dep.find("path");
if (ditr == dep.end())
return errorScenario(masonScenarion.string() + " object of unexpected format in dependecies");
nlohmann::json path = *ditr;
if (!path.is_string())
return errorScenario(masonScenarion.string() + " object of unexpected format in dependecies");
col->addSource(path);
}
break;
default:
return errorScenario(masonScenarion.string() + " has unexpected entries in dependecies");
}
}
if (!readMasonDependencies(deps, masonManifest))
return false;
}
type = mason;
info(location.string() + " seems to be a mason project");
info(location.string() + " seems to be a valid mason project");
return true;
}
return false;
}
bool Component::readMasonDependencies(const nlohmann::json& deps, const std::string& manifestPath) {
if (!deps.is_array())
return errorScenario(manifestPath + " dependencies are not organized as an array");
for (const nlohmann::json& dep : deps) {
std::shared_ptr<Collection> col = collection.lock();
switch (dep.type()) {
case nlohmann::json::value_t::string:
col->addSource(dep);
break;
case nlohmann::json::value_t::object: {
nlohmann::json::const_iterator ditr = dep.find("path");
if (ditr == dep.end())
return errorScenario(manifestPath + " object of unexpected format in dependecies");
nlohmann::json path = *ditr;
if (!path.is_string())
return errorScenario(manifestPath + " object of unexpected format in dependecies");
col->addSource(path);
}
break;
default:
return errorScenario(manifestPath + " has unexpected entries in dependecies");
}
}
return true;
}
bool Component::errorScenario(const std::string& message) {
major(message);
scenario = std::nullopt;
manifest = std::nullopt;
return false;
return false;
}
@ -124,11 +139,67 @@ void Component::build(const std::filesystem::path& destination, const std::strin
throw WrongState(state, "build");
state = building;
info("Building " + location.string() + " to " + destination.string());
switch (type) {
case file:
buildAsFile(destination);
break;
case directory:
buildAsDiractory(destination);
break;
case mason:
buildAsMason(destination, target);
break;
default:
break;
}
state = done;
}
void Component::buildAsFile(const std::filesystem::path& destination) {
std::filesystem::copy(location, destination/location.filename());
}
void Component::buildAsDiractory(const std::filesystem::path& destination) {
std::filesystem::copy(location, destination/location.filename(),
std::filesystem::copy_options::recursive |
std::filesystem::copy_options::overwrite_existing
);
}
std::string Component::getLibrariesPath() const {
//TODO may be it makes sence to cache
if (type != mason)
throw WrongType(type, "getLibrariesPath");
const nlohmann::json& mnfst = manifest.value();
nlohmann::json::const_iterator itr = mnfst.find("libraries");
if (itr == mnfst.end())
return "";
const nlohmann::json& libs = *itr;
if (libs.is_string())
return libs;
warn("Mason manifest " + (location/masonJSON).string()
+ " has field \"libraries\" which is not string, ignoring it");
return "";
}
std::filesystem::path Component::getLocation() const {
return location;
}
bool Component::successfullyRead() const {
return state > reading && state != error;
}
void Component::buildAsMason(const std::filesystem::path& destination, const std::string& target) {
warn("mason build is not implemented yet");
}
Component::State Component::getState() const {
return state;
}
@ -139,5 +210,10 @@ Component::Type Component::getType() const {
Component::WrongState::WrongState(State state, const std::string& action):
std::runtime_error("An attempt to perform action \"" + action
+ "\" on a wrong state \"" + stringStates[state].data() + '\"')
+ "\" on a wrong component state \"" + stringStates[state].data() + '\"')
{}
Component::WrongType::WrongType(Type type, const std::string& action):
std::runtime_error("An attempt to perform an action \"" + action
+ "\" on a wrong component type \"" + stringTypes[type].data() + '\"')
{}