targets and names
This commit is contained in:
parent
4843fcc77f
commit
cc4d8d1fc3
@ -49,7 +49,7 @@ Collection::Collection(
|
|||||||
}
|
}
|
||||||
|
|
||||||
taskManager->queue(
|
taskManager->queue(
|
||||||
std::bind(&Component::build, root.get(), destination, target),
|
std::bind(&Component::build, root.get(), destination, target, false),
|
||||||
std::bind(&Collection::rootBuilt, this, std::placeholders::_1)
|
std::bind(&Collection::rootBuilt, this, std::placeholders::_1)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -120,7 +120,7 @@ void Collection::sourceRead(const std::string& source, TaskManager::Error err) {
|
|||||||
readingSources.erase(itr);
|
readingSources.erase(itr);
|
||||||
|
|
||||||
taskManager->queue(
|
taskManager->queue(
|
||||||
std::bind(&Component::build, res.first->second.get(), destination/librariesPath, target),
|
std::bind(&Component::build, res.first->second.get(), destination/librariesPath, target, true),
|
||||||
std::bind(&Collection::sourceBuilt, this, source, std::placeholders::_1)
|
std::bind(&Collection::sourceBuilt, this, source, std::placeholders::_1)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -41,14 +41,16 @@ constexpr std::array<std::string_view, Component::unknown + 1> stringTypes {
|
|||||||
Component::Component(
|
Component::Component(
|
||||||
const std::filesystem::path& path,
|
const std::filesystem::path& path,
|
||||||
Collection* collection,
|
Collection* collection,
|
||||||
const std::shared_ptr<Logger>& logger
|
const std::shared_ptr<Logger>& logger,
|
||||||
|
const std::string& name
|
||||||
):
|
):
|
||||||
Loggable(logger),
|
Loggable(logger),
|
||||||
state(initial),
|
state(initial),
|
||||||
type(unknown),
|
type(unknown),
|
||||||
collection(collection),
|
collection(collection),
|
||||||
location(path),
|
location(path),
|
||||||
manifest(std::nullopt)
|
manifest(std::nullopt),
|
||||||
|
name(name)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void Component::read() {
|
void Component::read() {
|
||||||
@ -62,11 +64,16 @@ void Component::read() {
|
|||||||
case std::filesystem::file_type::directory:
|
case std::filesystem::file_type::directory:
|
||||||
type = directory;
|
type = directory;
|
||||||
state = ready;
|
state = ready;
|
||||||
tryReadingBuildScenarios();
|
if (!tryReadingBuildScenarios() && name.empty())
|
||||||
|
name = location.filename();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case std::filesystem::file_type::regular:
|
case std::filesystem::file_type::regular:
|
||||||
type = file;
|
type = file;
|
||||||
state = ready;
|
state = ready;
|
||||||
|
if (name.empty())
|
||||||
|
name = location.filename();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
warn(location.string() + " doesn't appear to be a file nor a directory");
|
warn(location.string() + " doesn't appear to be a file nor a directory");
|
||||||
@ -75,9 +82,11 @@ void Component::read() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Component::tryReadingBuildScenarios() {
|
bool Component::tryReadingBuildScenarios() {
|
||||||
if (readAsMason())
|
if (readAsMason())
|
||||||
return;
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Component::readAsMason() {
|
bool Component::readAsMason() {
|
||||||
@ -106,6 +115,17 @@ bool Component::readAsMason() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (name.empty()) {
|
||||||
|
std::optional<std::string> manifestName = tryStringValue(mnfst, "name");
|
||||||
|
if (manifestName.has_value())
|
||||||
|
name = manifestName.value();
|
||||||
|
|
||||||
|
if (name.empty()) {
|
||||||
|
major("Couldn't define name of the project at " + location.string() + ", using directory name as project name");
|
||||||
|
name = location.filename();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type = mason;
|
type = mason;
|
||||||
info(location.string() + " seems to be a valid mason project");
|
info(location.string() + " seems to be a valid mason project");
|
||||||
return true;
|
return true;
|
||||||
@ -151,7 +171,7 @@ bool Component::errorScenario(const std::string& message) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Component::build(const std::filesystem::path& destination, const std::string& target) {
|
void Component::build(const std::filesystem::path& destination, const std::string& target, bool useName) {
|
||||||
if (state != ready)
|
if (state != ready)
|
||||||
throw WrongState(state, "build");
|
throw WrongState(state, "build");
|
||||||
|
|
||||||
@ -160,13 +180,23 @@ void Component::build(const std::filesystem::path& destination, const std::strin
|
|||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case file:
|
case file:
|
||||||
buildAsFile(destination);
|
if (useName)
|
||||||
|
buildAsFile(destination/name);
|
||||||
|
else
|
||||||
|
buildAsFile(destination);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case directory:
|
case directory:
|
||||||
buildAsDirectory(destination);
|
if (useName)
|
||||||
|
buildAsDirectory(destination/name);
|
||||||
|
else
|
||||||
|
buildAsDirectory(destination);
|
||||||
break;
|
break;
|
||||||
case mason:
|
case mason:
|
||||||
buildAsMason(destination, target);
|
if (useName)
|
||||||
|
buildAsMason(destination/name, target);
|
||||||
|
else
|
||||||
|
buildAsMason(destination, target);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -174,13 +204,13 @@ void Component::build(const std::filesystem::path& destination, const std::strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Component::buildAsFile(const std::filesystem::path& destination) {
|
void Component::buildAsFile(const std::filesystem::path& destination) {
|
||||||
copyFile(location, destination/location.filename());
|
copyFile(location, destination);
|
||||||
|
|
||||||
state = done;
|
state = done;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Component::buildAsDirectory(const std::filesystem::path& destination) {
|
void Component::buildAsDirectory(const std::filesystem::path& destination) {
|
||||||
std::filesystem::copy(location, destination/location.filename(),
|
std::filesystem::copy(location, destination,
|
||||||
std::filesystem::copy_options::recursive |
|
std::filesystem::copy_options::recursive |
|
||||||
std::filesystem::copy_options::overwrite_existing
|
std::filesystem::copy_options::overwrite_existing
|
||||||
);
|
);
|
||||||
@ -219,7 +249,7 @@ bool Component::successfullyBuilt() const {
|
|||||||
return state == done;
|
return state == done;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Component::buildAsMason(const std::filesystem::path& destination, const std::string& target) {
|
void Component::buildAsMason(const std::filesystem::path& destination, std::string target) {
|
||||||
const nlohmann::json& mnfst = manifest.value();
|
const nlohmann::json& mnfst = manifest.value();
|
||||||
nlohmann::json::const_iterator itr = mnfst.find("build");
|
nlohmann::json::const_iterator itr = mnfst.find("build");
|
||||||
if (itr == mnfst.end()) {
|
if (itr == mnfst.end()) {
|
||||||
@ -230,11 +260,13 @@ void Component::buildAsMason(const std::filesystem::path& destination, const std
|
|||||||
|
|
||||||
const nlohmann::json& build = *itr;
|
const nlohmann::json& build = *itr;
|
||||||
if (!build.is_array()) {
|
if (!build.is_array()) {
|
||||||
warn("Mason project at " + location.string() + " has unexpected \"build\" section in its manifest");
|
warn("Mason project at " + location.string() + " has unexpected type \"build\" section in its manifest");
|
||||||
state = done;
|
state = done;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
target = validateMasonTarget(target);
|
||||||
|
|
||||||
for (const nlohmann::json& entry : build) {
|
for (const nlohmann::json& entry : build) {
|
||||||
switch (entry.type()) {
|
switch (entry.type()) {
|
||||||
case nlohmann::json::value_t::string:
|
case nlohmann::json::value_t::string:
|
||||||
@ -244,7 +276,7 @@ void Component::buildAsMason(const std::filesystem::path& destination, const std
|
|||||||
masonFilesArray(entry, destination);
|
masonFilesArray(entry, destination);
|
||||||
break;
|
break;
|
||||||
case nlohmann::json::value_t::object:
|
case nlohmann::json::value_t::object:
|
||||||
if (allowedForTarget(entry, target)) {
|
if (allowedForMasonTarget(entry, target)) {
|
||||||
nlohmann::json::const_iterator fitr = entry.find("files");
|
nlohmann::json::const_iterator fitr = entry.find("files");
|
||||||
if (fitr != entry.end()) {
|
if (fitr != entry.end()) {
|
||||||
const nlohmann::json& files = *fitr;
|
const nlohmann::json& files = *fitr;
|
||||||
@ -254,6 +286,8 @@ void Component::buildAsMason(const std::filesystem::path& destination, const std
|
|||||||
warn(std::string("Unexpected ") + entry.type_name()
|
warn(std::string("Unexpected ") + entry.type_name()
|
||||||
+ " of files subsection of build section of its manifest in "
|
+ " of files subsection of build section of its manifest in "
|
||||||
+ location.string() + ", ignoring");
|
+ location.string() + ", ignoring");
|
||||||
|
} else {
|
||||||
|
masonFileObject(entry, destination);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -284,20 +318,9 @@ void Component::masonFilesArray(const nlohmann::json& files, const std::filesyst
|
|||||||
case nlohmann::json::value_t::string:
|
case nlohmann::json::value_t::string:
|
||||||
copyFile(location/entry, destination/entry);
|
copyFile(location/entry, destination/entry);
|
||||||
break;
|
break;
|
||||||
case nlohmann::json::value_t::object: {
|
case nlohmann::json::value_t::object:
|
||||||
std::optional<std::string> src = getFileSource(entry);
|
masonFileObject(entry, destination);
|
||||||
if (!src.has_value()) {
|
break;
|
||||||
warn("Couldn't understand file source processing file array in " + location.string() + ", ignoring");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
std::optional<std::string> dst = getFileTarget(entry);
|
|
||||||
if (!src.has_value()) {
|
|
||||||
warn("Couldn't understand file destination processing file array in " + location.string() + ", ignoring");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
copyFile(location/src.value(), destination/src.value());
|
|
||||||
} break;
|
|
||||||
default:
|
default:
|
||||||
warn(std::string("Unexpected ") + entry.type_name()
|
warn(std::string("Unexpected ") + entry.type_name()
|
||||||
+ " in files subsection of build section of manifest in "
|
+ " in files subsection of build section of manifest in "
|
||||||
@ -306,7 +329,65 @@ void Component::masonFilesArray(const nlohmann::json& files, const std::filesyst
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Component::allowedForTarget(const nlohmann::json& object, const std::string& target) const {
|
bool Component::masonFileObject(const nlohmann::json& object, const std::filesystem::path& destination) {
|
||||||
|
std::optional<std::string> src = getFileSource(object);
|
||||||
|
if (!src.has_value()) {
|
||||||
|
warn("Couldn't understand file source processing file array in " + location.string() + ", ignoring");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
std::optional<std::string> dst = getFileTarget(object);
|
||||||
|
if (!src.has_value()) {
|
||||||
|
warn("Couldn't understand file destination processing file array in " + location.string() + ", ignoring");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
copyFile(location/src.value(), destination/dst.value());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Component::validateMasonTarget(std::string target) const {
|
||||||
|
const nlohmann::json& mnfst = manifest.value();
|
||||||
|
std::set<std::string> allowedTarges;
|
||||||
|
|
||||||
|
nlohmann::json::const_iterator itr = mnfst.find("targets");
|
||||||
|
if (itr != mnfst.end()) {
|
||||||
|
const nlohmann::json& targets = *itr;
|
||||||
|
if (targets.is_array()) {
|
||||||
|
for (const nlohmann::json& entry : targets) {
|
||||||
|
if (entry.is_string())
|
||||||
|
allowedTarges.emplace(entry);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
warn("Mason project at " + location.string() + " has unexpected type \"targets\" section in its manifest, ignoring");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
minor("Mason project at " + location.string() + " has no \"targets\" section, trying to figure out utilized targets from \"build\" section");
|
||||||
|
const nlohmann::json& build = mnfst.at("build");
|
||||||
|
for (const nlohmann::json& entry : build) {
|
||||||
|
if (entry.is_object())
|
||||||
|
getMasonTargets(entry, allowedTarges);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (allowedTarges.count(target) > 0)
|
||||||
|
return target;
|
||||||
|
|
||||||
|
minor("Mason project at " + location.string() + " doesn't seem to support target \"" + target + "\"");
|
||||||
|
std::optional<std::string> defaultTarget = tryStringValue(mnfst, "defaultTarget");
|
||||||
|
if (defaultTarget.has_value()) {
|
||||||
|
target = defaultTarget.value();
|
||||||
|
minor("Mason project at " + location.string() + " will use project default target \"" + target + "\" instead of specified");
|
||||||
|
} else {
|
||||||
|
target = "default";
|
||||||
|
warn("Mason project at " + location.string() + " will use hardcoded default target \""
|
||||||
|
+ target + "\" because field \"defaultTarget\" is either abscent or invalid");
|
||||||
|
}
|
||||||
|
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
//this method could utilize Component::getMasonTargets but it doesn't because this way has less overhead
|
||||||
|
bool Component::allowedForMasonTarget(const nlohmann::json& object, const std::string& target) const {
|
||||||
nlohmann::json::const_iterator itr = object.find("target");
|
nlohmann::json::const_iterator itr = object.find("target");
|
||||||
if (itr != object.end()) {
|
if (itr != object.end()) {
|
||||||
const nlohmann::json& tg = *itr;
|
const nlohmann::json& tg = *itr;
|
||||||
@ -340,6 +421,35 @@ bool Component::allowedForTarget(const nlohmann::json& object, const std::string
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Component::getMasonTargets(const nlohmann::json& object, std::set<std::string>& out) const {
|
||||||
|
nlohmann::json::const_iterator itr = object.find("target");
|
||||||
|
if (itr != object.end()) {
|
||||||
|
const nlohmann::json& tg = *itr;
|
||||||
|
if (tg.is_string())
|
||||||
|
out.emplace(tg);
|
||||||
|
else
|
||||||
|
warn("\"target\" in build section has unexpected type, ignoring");
|
||||||
|
}
|
||||||
|
|
||||||
|
itr = object.find("targets");
|
||||||
|
if (itr != object.end()) {
|
||||||
|
const nlohmann::json& targets = *itr;
|
||||||
|
if (targets.is_array()) {
|
||||||
|
for (const nlohmann::json& entry : targets) {
|
||||||
|
if (entry.is_string())
|
||||||
|
out.emplace(entry);
|
||||||
|
else
|
||||||
|
warn("one of the targets in \"targets\" in build section has unexpected type, ignoring it");
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
warn("\"targets\" in build section has unexpected type, ignoring");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO may be notTarget and notTargets?
|
||||||
|
}
|
||||||
|
|
||||||
std::optional<std::string> Component::getFileSource(const nlohmann::json& object) const {
|
std::optional<std::string> Component::getFileSource(const nlohmann::json& object) const {
|
||||||
for (const std::string_view& key : sourceVariants) {
|
for (const std::string_view& key : sourceVariants) {
|
||||||
std::optional<std::string> value = tryStringValue(object, key.data());
|
std::optional<std::string> value = tryStringValue(object, key.data());
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
#include <set>
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
#include "loggable.h"
|
#include "loggable.h"
|
||||||
@ -39,33 +40,38 @@ public:
|
|||||||
Component(
|
Component(
|
||||||
const std::filesystem::path& path,
|
const std::filesystem::path& path,
|
||||||
Collection* collection,
|
Collection* collection,
|
||||||
const std::shared_ptr<Logger>& logger
|
const std::shared_ptr<Logger>& logger,
|
||||||
|
const std::string& name = ""
|
||||||
);
|
);
|
||||||
|
|
||||||
Type getType() const;
|
Type getType() const;
|
||||||
State getState() const;
|
State getState() const;
|
||||||
std::filesystem::path getLocation() const;
|
std::filesystem::path getLocation() const;
|
||||||
std::string getLibrariesPath() const;
|
std::string getLibrariesPath() const;
|
||||||
|
std::string getName() const;
|
||||||
bool successfullyRead() const;
|
bool successfullyRead() const;
|
||||||
bool successfullyBuilt() const;
|
bool successfullyBuilt() const;
|
||||||
|
|
||||||
void read();
|
void read();
|
||||||
void build(const std::filesystem::path& destination, const std::string& target);
|
void build(const std::filesystem::path& destination, const std::string& target, bool useName = true);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void tryReadingBuildScenarios();
|
bool tryReadingBuildScenarios();
|
||||||
bool readAsMason();
|
bool readAsMason();
|
||||||
bool errorScenario(const std::string& message);
|
bool errorScenario(const std::string& message);
|
||||||
|
|
||||||
void buildAsFile(const std::filesystem::path& destination);
|
void buildAsFile(const std::filesystem::path& destination);
|
||||||
void buildAsDirectory(const std::filesystem::path& destination);
|
void buildAsDirectory(const std::filesystem::path& destination);
|
||||||
void buildAsMason(const std::filesystem::path& destination, const std::string& target);
|
void buildAsMason(const std::filesystem::path& destination, std::string target);
|
||||||
|
|
||||||
bool readMasonDependencies(const nlohmann::json& deps, const std::string& manifestPath);
|
bool readMasonDependencies(const nlohmann::json& deps, const std::string& manifestPath);
|
||||||
void copyFile(const std::filesystem::path& from, const std::filesystem::path& to) const;
|
void copyFile(const std::filesystem::path& from, const std::filesystem::path& to) const;
|
||||||
|
|
||||||
|
std::string validateMasonTarget(std::string target) const;
|
||||||
void masonFilesArray(const nlohmann::json& files, const std::filesystem::path& destination);
|
void masonFilesArray(const nlohmann::json& files, const std::filesystem::path& destination);
|
||||||
bool allowedForTarget(const nlohmann::json& object, const std::string& target) const;
|
bool masonFileObject(const nlohmann::json& object, const std::filesystem::path& destination);
|
||||||
|
bool allowedForMasonTarget(const nlohmann::json& object, const std::string& target) const;
|
||||||
|
void getMasonTargets(const nlohmann::json& object, std::set<std::string>& out) const;
|
||||||
|
|
||||||
std::optional<std::string> getFileSource(const nlohmann::json& object) const;
|
std::optional<std::string> getFileSource(const nlohmann::json& object) const;
|
||||||
std::optional<std::string> getFileTarget(const nlohmann::json& object) const;
|
std::optional<std::string> getFileTarget(const nlohmann::json& object) const;
|
||||||
@ -78,6 +84,7 @@ private:
|
|||||||
Collection* collection;
|
Collection* collection;
|
||||||
std::filesystem::path location;
|
std::filesystem::path location;
|
||||||
std::optional<nlohmann::json> manifest;
|
std::optional<nlohmann::json> manifest;
|
||||||
|
std::string name;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Component::WrongState : public std::runtime_error {
|
class Component::WrongState : public std::runtime_error {
|
||||||
|
@ -12,5 +12,12 @@
|
|||||||
"https://git.macaw.me/blue/mason/archive/main.tar.gz",
|
"https://git.macaw.me/blue/mason/archive/main.tar.gz",
|
||||||
"https://git.macaw.me/blue/mason/raw/branch/main/src2/atomicmutex.h"
|
"https://git.macaw.me/blue/mason/raw/branch/main/src2/atomicmutex.h"
|
||||||
],
|
],
|
||||||
|
"build": [
|
||||||
|
"mason.json",
|
||||||
|
{
|
||||||
|
"src" : "mason.json",
|
||||||
|
"dst" : "another/mason.json"
|
||||||
|
}
|
||||||
|
],
|
||||||
"libraries": "lib"
|
"libraries": "lib"
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user