1023 lines
55 KiB
C++
1023 lines
55 KiB
C++
// SPDX-License-Identifier: MPL-2.0
|
|
#ifndef VYBUILD_LIB_H
|
|
#define VYBUILD_LIB_H
|
|
#include <string>
|
|
#include <fstream>
|
|
#include <filesystem>
|
|
#include <iostream>
|
|
#include <variant>
|
|
#include <vector>
|
|
#include <unistd.h>
|
|
#include <limits.h>
|
|
#include "json.hpp"
|
|
#include "xxhash.h"
|
|
#include <uuid/uuid.h>
|
|
using json=nlohmann::json;
|
|
namespace fs=std::filesystem;
|
|
const std::string syntax_version="0.1";
|
|
const std::vector<std::string> threaded_actions={"run_submodule","run_submodule_if","run_actions_parallel","vyld_compilation","run_submodule_parallel","compile_multiple_cpp"};
|
|
namespace vybuild {
|
|
namespace fat32 {
|
|
void load_crypto_lib(std::string path);
|
|
bool is_crypto_lib_loaded();
|
|
bool is_vftm_target_set();
|
|
uint8_t* get_manifest_keypair_buffer();
|
|
void create_fat32(std::string key,size_t size);
|
|
void add_directory_fat32(std::string key,std::string full_path);
|
|
void add_file_fat32(std::string key,std::string full_path,uint8_t *buffer_in,size_t file_size,bool is_vftm_target);
|
|
std::vector<uint8_t> export_fat32(std::string key,bool generate_vftm,std::string disk_guid_var,std::string efi_part_unique_guid_var);
|
|
}
|
|
namespace disk {
|
|
std::array<uint8_t,16> uuid4_to_bytes(const std::string& uuid);
|
|
void create_disk(std::string key,size_t size,std::string disk_guid);
|
|
void add_partition(std::string key,size_t partition_size_bytes,std::string type_guid,std::string unique_guid,uint64_t attributes,std::string name,uint8_t* in_buf,size_t in_size);
|
|
std::vector<uint8_t> export_disk(std::string key);
|
|
}
|
|
namespace condition {
|
|
bool evaluate_condition(const json& condition);
|
|
}
|
|
namespace parser {
|
|
std::string root_folder_parsing(const std::string& root_folder,const std::string& file);
|
|
std::vector<std::string> vector_string_vars(std::vector<std::string> vector_in);
|
|
std::string string_vars(std::string string_in);
|
|
std::vector<std::string> vector_string_path_completions(std::vector<std::string> vector_in,std::string suffix);
|
|
}
|
|
namespace vars {
|
|
std::vector<std::string>& get_global_variables_list();
|
|
void set_global_variable(std::string key,std::string value);
|
|
std::string get_global_variable(std::string key);
|
|
}
|
|
namespace cache {
|
|
void init_cache(bool enable_smart_cache);
|
|
void store_file(std::string key,fs::path file_path);
|
|
bool cache_contains(std::string key);
|
|
void extract_file(std::string key,fs::path output_path);
|
|
void clean_cache();
|
|
std::string xxhash_to_string(XXH128_hash_t hash);
|
|
}
|
|
namespace actions {
|
|
void check_arg_string(const json& args,std::string field_name);
|
|
void check_arg_vector_string(const json& args,std::string field_name);
|
|
enum class ActionStatus {
|
|
Success,
|
|
Fail,
|
|
SystemError,
|
|
ExitSuccess,
|
|
ExitFail
|
|
};
|
|
class RunSubmoduleAction {
|
|
public:
|
|
RunSubmoduleAction(const json& args,std::string root_folder) {
|
|
char path[PATH_MAX];
|
|
getcwd(path,sizeof(path));
|
|
chdir(root_folder.c_str());
|
|
check_arg_string(args,"file");
|
|
if (!args.contains("wait")) throw std::runtime_error("Wait isn't provided.");
|
|
if (!args["wait"].is_boolean()) throw std::runtime_error("Wait isn't a boolean");
|
|
if (!args.contains("block_if_fail")) throw std::runtime_error("Block if fail isn't provided.");
|
|
if (!args["block_if_fail"].is_boolean()) throw std::runtime_error("Block if fail isn't a boolean");
|
|
this->file_variables=args["file_variables"].get<bool>();
|
|
this->file=args["file"].get<std::string>();
|
|
this->wait=args["wait"].get<bool>();
|
|
this->block_if_fail=args["block_if_fail"].get<bool>();
|
|
chdir(path);
|
|
}
|
|
bool file_variables;
|
|
std::string file;
|
|
bool wait;
|
|
bool block_if_fail;
|
|
ActionStatus run_action();
|
|
};
|
|
class RunCommandWaitAction {
|
|
public:
|
|
RunCommandWaitAction(const json& args) {
|
|
check_arg_vector_string(args,"command");
|
|
if (!args.contains("show_output")) throw std::runtime_error("Show output isn't provided.");
|
|
if (!args["show_output"].is_string()) throw std::runtime_error("Show output isn't a string");
|
|
if (args["show_output"]!="live" && args["show_output"]!="on_failure" && args["show_output"]!="silent") {
|
|
throw std::runtime_error("\""+args["show_output"].get<std::string>()+"\" isn't a valid output mode.");
|
|
}
|
|
if (!args.contains("success_status")) throw std::runtime_error("Success status isn't provided.");
|
|
if (!args["success_status"].is_array()) throw std::runtime_error("Success status isn't a boolean");
|
|
for (auto& arg:args["success_status"]) {
|
|
if (!arg.is_number_integer()) throw std::runtime_error("One of the status code isn't an integer.");
|
|
}
|
|
if (!args.contains("ignore_success_status")) throw std::runtime_error("Ignore success status isn't provided.");
|
|
if (!args["ignore_success_status"].is_boolean()) throw std::runtime_error("Ignore success status isn't a boolean");
|
|
this->command_variables=args["command_variables"].get<bool>();
|
|
this->command=args["command"].get<std::vector<std::string>>();
|
|
this->show_output=args["show_output"].get<std::string>();
|
|
this->success_status=args["success_status"].get<std::vector<int>>();
|
|
this->ignore_success_status=args["ignore_success_status"].get<bool>();
|
|
}
|
|
bool command_variables;
|
|
std::vector<std::string> command;
|
|
std::string show_output;
|
|
std::vector<int> success_status;
|
|
bool ignore_success_status;
|
|
ActionStatus run_action();
|
|
};
|
|
class SaveCommandContentAction {
|
|
public:
|
|
SaveCommandContentAction(const json& args) {
|
|
check_arg_vector_string(args,"command");
|
|
if (!args.contains("success_status")) throw std::runtime_error("Success status isn't provided.");
|
|
if (!args["success_status"].is_array()) throw std::runtime_error("Success status isn't a boolean");
|
|
for (auto& arg:args["success_status"]) {
|
|
if (!arg.is_number_integer()) throw std::runtime_error("One of the status code isn't an integer.");
|
|
}
|
|
if (!args.contains("ignore_success_status")) throw std::runtime_error("Ignore success status isn't provided.");
|
|
if (!args["ignore_success_status"].is_boolean()) throw std::runtime_error("Ignore success status isn't a boolean");
|
|
check_arg_string(args,"command_output_file");
|
|
this->command_variables=args["command_variables"].get<bool>();
|
|
this->command=args["command"].get<std::vector<std::string>>();
|
|
this->success_status=args["success_status"].get<std::vector<int>>();
|
|
this->ignore_success_status=args["ignore_success_status"].get<bool>();
|
|
this->command_output_file_variables=args["command_output_file_variables"].get<bool>();
|
|
this->command_output_file=args["command_output_file"].get<std::string>();
|
|
}
|
|
bool command_variables;
|
|
std::vector<std::string> command;
|
|
std::vector<int> success_status;
|
|
bool ignore_success_status;
|
|
bool command_output_file_variables;
|
|
std::string command_output_file;
|
|
ActionStatus run_action();
|
|
};
|
|
class CompileOneAsmAction {
|
|
public:
|
|
CompileOneAsmAction(const json& args) {
|
|
check_arg_string(args,"source");
|
|
check_arg_string(args,"assembler");
|
|
check_arg_vector_string(args,"pre_arguments");
|
|
check_arg_vector_string(args,"post_arguments");
|
|
check_arg_string(args,"output_file");
|
|
if (!args.contains("success_status")) throw std::runtime_error("Success status isn't provided.");
|
|
if (!args["success_status"].is_array()) throw std::runtime_error("Success status isn't a boolean");
|
|
for (auto& arg:args["success_status"]) {
|
|
if (!arg.is_number_integer()) throw std::runtime_error("One of the status code isn't an integer.");
|
|
}
|
|
if (!args.contains("ignore_success_status")) throw std::runtime_error("Ignore success status isn't provided.");
|
|
if (!args["ignore_success_status"].is_boolean()) throw std::runtime_error("Ignore success status isn't a boolean");
|
|
if (!args.contains("cache_authorized")) throw std::runtime_error("Cache authorized isn't provided.");
|
|
if (!args["cache_authorized"].is_boolean()) throw std::runtime_error("Cache authorized isn't a boolean");
|
|
this->source_variables=args["source_variables"].get<bool>();
|
|
this->assembler_variables=args["assembler_variables"].get<bool>();
|
|
this->pre_arguments_variables=args["pre_arguments_variables"].get<bool>();
|
|
this->post_arguments_variables=args["post_arguments_variables"].get<bool>();
|
|
this->output_file_variables=args["output_file_variables"].get<bool>();
|
|
this->source=args["source"].get<std::string>();
|
|
this->assembler=args["assembler"].get<std::string>();
|
|
this->output_file=args["output_file"].get<std::string>();
|
|
this->pre_arguments=args["pre_arguments"].get<std::vector<std::string>>();
|
|
this->post_arguments=args["post_arguments"].get<std::vector<std::string>>();
|
|
this->success_status=args["success_status"].get<std::vector<int>>();
|
|
this->ignore_success_status=args["ignore_success_status"].get<bool>();
|
|
this->cache_authorized=args["cache_authorized"].get<bool>();
|
|
}
|
|
bool source_variables;
|
|
std::string source;
|
|
bool assembler_variables;
|
|
std::string assembler;
|
|
bool pre_arguments_variables;
|
|
std::vector<std::string> pre_arguments;
|
|
bool post_arguments_variables;
|
|
std::vector<std::string> post_arguments;
|
|
bool output_file_variables;
|
|
std::string output_file;
|
|
std::vector<int> success_status;
|
|
bool ignore_success_status;
|
|
bool cache_authorized;
|
|
ActionStatus run_action();
|
|
};
|
|
class EnsureFolderExistenceAction {
|
|
public:
|
|
EnsureFolderExistenceAction(const json& args) {
|
|
check_arg_string(args,"path");
|
|
this->path_variables=args["path_variables"].get<bool>();
|
|
this->path=args["path"].get<std::string>();
|
|
}
|
|
bool path_variables;
|
|
std::string path;
|
|
ActionStatus run_action();
|
|
};
|
|
class MoveFileAction {
|
|
public:
|
|
MoveFileAction(const json& args) {
|
|
check_arg_string(args,"source_file");
|
|
check_arg_string(args,"destination_folder");
|
|
this->source_file_variables=args["source_file_variables"].get<bool>();
|
|
this->source_file=args["source_file"].get<std::string>();
|
|
this->destination_folder_variables=args["destination_folder_variables"].get<bool>();
|
|
this->destination_folder=args["destination_folder"].get<std::string>();
|
|
}
|
|
bool source_file_variables;
|
|
std::string source_file;
|
|
bool destination_folder_variables;
|
|
std::string destination_folder;
|
|
ActionStatus run_action();
|
|
};
|
|
class CompileOneCppAction {
|
|
public:
|
|
CompileOneCppAction(const json& args) {
|
|
check_arg_string(args,"source");
|
|
check_arg_string(args,"compiler");
|
|
check_arg_vector_string(args,"pre_arguments");
|
|
check_arg_vector_string(args,"post_arguments");
|
|
check_arg_string(args,"output_file");
|
|
check_arg_string(args,"headers_command");
|
|
if (!args.contains("success_status")) throw std::runtime_error("Success status isn't provided.");
|
|
if (!args["success_status"].is_array()) throw std::runtime_error("Success status isn't a boolean");
|
|
for (auto& arg:args["success_status"]) {
|
|
if (!arg.is_number_integer()) throw std::runtime_error("One of the status code isn't an integer.");
|
|
}
|
|
if (!args.contains("ignore_success_status")) throw std::runtime_error("Ignore success status isn't provided.");
|
|
if (!args["ignore_success_status"].is_boolean()) throw std::runtime_error("Ignore success status isn't a boolean");
|
|
if (!args.contains("cache_authorized")) throw std::runtime_error("Cache authorized isn't provided.");
|
|
if (!args["cache_authorized"].is_boolean()) throw std::runtime_error("Cache authorized isn't a boolean");
|
|
this->source_variables=args["source_variables"].get<bool>();
|
|
this->compiler_variables=args["compiler_variables"].get<bool>();
|
|
this->pre_arguments_variables=args["pre_arguments_variables"].get<bool>();
|
|
this->post_arguments_variables=args["post_arguments_variables"].get<bool>();
|
|
this->output_file_variables=args["output_file_variables"].get<bool>();
|
|
this->headers_command_variables=args["headers_command_variables"].get<bool>();
|
|
this->source=args["source"].get<std::string>();
|
|
this->compiler=args["compiler"].get<std::string>();
|
|
this->output_file=args["output_file"].get<std::string>();
|
|
this->pre_arguments=args["pre_arguments"].get<std::vector<std::string>>();
|
|
this->post_arguments=args["post_arguments"].get<std::vector<std::string>>();
|
|
this->success_status=args["success_status"].get<std::vector<int>>();
|
|
this->ignore_success_status=args["ignore_success_status"].get<bool>();
|
|
this->cache_authorized=args["cache_authorized"].get<bool>();
|
|
this->headers_command=args["headers_command"].get<std::string>();
|
|
}
|
|
bool source_variables;
|
|
std::string source;
|
|
bool compiler_variables;
|
|
std::string compiler;
|
|
bool pre_arguments_variables;
|
|
std::vector<std::string> pre_arguments;
|
|
bool post_arguments_variables;
|
|
std::vector<std::string> post_arguments;
|
|
bool output_file_variables;
|
|
std::string output_file;
|
|
std::vector<int> success_status;
|
|
bool ignore_success_status;
|
|
bool cache_authorized;
|
|
bool headers_command_variables;
|
|
std::string headers_command;
|
|
ActionStatus run_action();
|
|
};
|
|
class RunSubmoduleIfAction {
|
|
public:
|
|
RunSubmoduleIfAction(const json& args,std::string root_folder) {
|
|
char path[PATH_MAX];
|
|
getcwd(path,sizeof(path));
|
|
chdir(root_folder.c_str());
|
|
check_arg_string(args,"file");
|
|
if (!args.contains("wait")) throw std::runtime_error("Wait isn't provided.");
|
|
if (!args["wait"].is_boolean()) throw std::runtime_error("Wait isn't a boolean");
|
|
if (!args.contains("block_if_fail")) throw std::runtime_error("Block if fail isn't provided.");
|
|
if (!args["block_if_fail"].is_boolean()) throw std::runtime_error("Block if fail isn't a boolean");
|
|
if (!args.contains("condition")) throw std::runtime_error("Condition isn't provided.");
|
|
if (!args["condition"].is_object()) throw std::runtime_error("Condition isn't a dictionnary.");
|
|
this->condition=args["condition"];
|
|
this->file=args["file"].get<std::string>();
|
|
this->file=fs::absolute(fs::path(args["file"].get<std::string>()));
|
|
this->wait=args["wait"].get<bool>();
|
|
this->block_if_fail=args["block_if_fail"].get<bool>();
|
|
chdir(path);
|
|
}
|
|
json condition;
|
|
bool file_variables;
|
|
std::string file;
|
|
bool wait;
|
|
bool block_if_fail;
|
|
ActionStatus run_action();
|
|
};
|
|
class RunCommandWaitDirAction {
|
|
public:
|
|
RunCommandWaitDirAction(const json& args) {
|
|
check_arg_vector_string(args,"command");
|
|
check_arg_string(args,"working_dir");
|
|
if (!args.contains("show_output")) throw std::runtime_error("Show output isn't provided.");
|
|
if (!args["show_output"].is_string()) throw std::runtime_error("Show output isn't a string");
|
|
if (args["show_output"]!="live" && args["show_output"]!="on_failure" && args["show_output"]!="silent") {
|
|
throw std::runtime_error("\""+args["show_output"].get<std::string>()+"\" isn't a valid output mode.");
|
|
}
|
|
if (!args.contains("success_status")) throw std::runtime_error("Success status isn't provided.");
|
|
if (!args["success_status"].is_array()) throw std::runtime_error("Success status isn't a boolean");
|
|
for (auto& arg:args["success_status"]) {
|
|
if (!arg.is_number_integer()) throw std::runtime_error("One of the status code isn't an integer.");
|
|
}
|
|
if (!args.contains("ignore_success_status")) throw std::runtime_error("Ignore success status isn't provided.");
|
|
if (!args["ignore_success_status"].is_boolean()) throw std::runtime_error("Ignore success status isn't a boolean");
|
|
this->command_variables=args["command_variables"].get<bool>();
|
|
this->command=args["command"].get<std::vector<std::string>>();
|
|
this->show_output=args["show_output"].get<std::string>();
|
|
this->success_status=args["success_status"].get<std::vector<int>>();
|
|
this->ignore_success_status=args["ignore_success_status"].get<bool>();
|
|
this->working_dir_variables=args["working_dir_variables"].get<bool>();
|
|
this->working_dir=args["working_dir"].get<std::string>();
|
|
}
|
|
bool command_variables;
|
|
std::vector<std::string> command;
|
|
std::string show_output;
|
|
std::vector<int> success_status;
|
|
bool ignore_success_status;
|
|
bool working_dir_variables;
|
|
std::string working_dir;
|
|
ActionStatus run_action();
|
|
};
|
|
class CopyFolderAction {
|
|
public:
|
|
CopyFolderAction(const json& args) {
|
|
check_arg_string(args,"source_folder");
|
|
check_arg_string(args,"destination_folder");
|
|
this->source_folder_variables=args["source_folder_variables"].get<bool>();
|
|
this->source_folder=args["source_folder"].get<std::string>();
|
|
this->destination_folder_variables=args["destination_folder_variables"].get<bool>();
|
|
this->destination_folder=args["destination_folder"].get<std::string>();
|
|
}
|
|
bool source_folder_variables;
|
|
std::string source_folder;
|
|
bool destination_folder_variables;
|
|
std::string destination_folder;
|
|
ActionStatus run_action();
|
|
};
|
|
class ExtractFromCacheAction {
|
|
public:
|
|
ExtractFromCacheAction(const json& args) {
|
|
check_arg_string(args,"target");
|
|
check_arg_string(args,"output_file");
|
|
this->target_variables=args["target_variables"].get<bool>();
|
|
this->output_file_variables=args["output_file_variables"].get<bool>();
|
|
this->target=args["target"].get<std::string>();
|
|
this->output_file=args["output_file"].get<std::string>();
|
|
}
|
|
bool target_variables;
|
|
std::string target;
|
|
bool output_file_variables;
|
|
std::string output_file;
|
|
ActionStatus run_action();
|
|
};
|
|
class StoreInCacheAction {
|
|
public:
|
|
StoreInCacheAction(const json& args) {
|
|
check_arg_string(args,"key");
|
|
check_arg_string(args,"file");
|
|
this->key_variables=args["key_variables"].get<bool>();
|
|
this->file_variables=args["file_variables"].get<bool>();
|
|
this->overwrite_allowed=args["overwrite_allowed"].get<bool>();
|
|
this->key=args["key"].get<std::string>();
|
|
this->file=args["file"].get<std::string>();
|
|
}
|
|
bool key_variables;
|
|
std::string key;
|
|
bool file_variables;
|
|
std::string file;
|
|
bool overwrite_allowed;
|
|
ActionStatus run_action();
|
|
};
|
|
class EnsureFolderResetAction {
|
|
public:
|
|
EnsureFolderResetAction(const json& args) {
|
|
check_arg_string(args,"path");
|
|
this->path_variables=args["path_variables"].get<bool>();
|
|
this->path=args["path"].get<std::string>();
|
|
}
|
|
bool path_variables;
|
|
std::string path;
|
|
ActionStatus run_action();
|
|
};
|
|
class RunActionsIfAction {
|
|
public:
|
|
RunActionsIfAction(const json& args,bool is_threading_allowed,std::string root_folder) {
|
|
if (!args.contains("condition")) throw std::runtime_error("Condition isn't provided.");
|
|
if (!args["condition"].is_object()) throw std::runtime_error("Condition isn't a dictionnary.");
|
|
if (!args["actions"].is_array()) throw std::runtime_error("Provided actions aren't stored in a list.");
|
|
for (const auto& act:args["actions"]) {
|
|
if (!act.is_object()) throw std::runtime_error("One of the action isn't a dictionnary.");
|
|
if (!act.contains("action")) throw std::runtime_error("Action isn't provided.");
|
|
if (!act["action"].is_string()) throw std::runtime_error("Action isn't a string.");
|
|
if (find(threaded_actions.begin(),threaded_actions.end(),act["action"].get<std::string>())!=threaded_actions.end() && !is_threading_allowed) throw std::runtime_error("Multithreaded actions aren't allowed in this module, and so can not be executed from RunActionsIfAction.");
|
|
if (!act.contains("args")) throw std::runtime_error("Action arguments aren't provided.");
|
|
if (!act["args"].is_object()) throw std::runtime_error("Action arguments aren't stored in a dictionnary.");
|
|
actions.push_back(act);
|
|
}
|
|
this->condition=args["condition"];
|
|
this->is_threading_allowed=is_threading_allowed;
|
|
this->root_folder=root_folder;
|
|
}
|
|
json condition;
|
|
std::vector<json> actions;
|
|
bool is_threading_allowed;
|
|
std::string root_folder;
|
|
ActionStatus run_action();
|
|
};
|
|
class RunActionsIfElseAction {
|
|
public:
|
|
RunActionsIfElseAction(const json& args,bool is_threading_allowed,std::string root_folder) {
|
|
if (!args.contains("condition")) throw std::runtime_error("Condition isn't provided.");
|
|
if (!args["condition"].is_object()) throw std::runtime_error("Condition isn't a dictionnary.");
|
|
if (!args.contains("actions_if")) throw std::runtime_error("No actions are provided.");
|
|
if (!args["actions_if"].is_array()) throw std::runtime_error("Provided actions aren't stored in a list.");
|
|
for (const auto& act:args["actions_if"]) {
|
|
if (!act.is_object()) throw std::runtime_error("One of the action isn't a dictionnary.");
|
|
if (!act.contains("action")) throw std::runtime_error("Action isn't provided.");
|
|
if (!act["action"].is_string()) throw std::runtime_error("Action isn't a string.");
|
|
if (find(threaded_actions.begin(),threaded_actions.end(),act["action"].get<std::string>())!=threaded_actions.end() && !is_threading_allowed) throw std::runtime_error("Multithreaded actions aren't allowed in this module, and so can not be executed from RunActionsIfAction.");
|
|
if (!act.contains("args")) throw std::runtime_error("Action arguments aren't provided.");
|
|
if (!act["args"].is_object()) throw std::runtime_error("Action arguments aren't stored in a dictionnary.");
|
|
actions_if.push_back(act);
|
|
}
|
|
if (!args.contains("actions_else")) throw std::runtime_error("No actions are provided.");
|
|
if (!args["actions_else"].is_array()) throw std::runtime_error("Provided actions aren't stored in a list.");
|
|
for (const auto& act:args["actions_else"]) {
|
|
if (!act.is_object()) throw std::runtime_error("One of the action isn't a dictionnary.");
|
|
if (!act.contains("action")) throw std::runtime_error("Action isn't provided.");
|
|
if (!act["action"].is_string()) throw std::runtime_error("Action isn't a string.");
|
|
if (find(threaded_actions.begin(),threaded_actions.end(),act["action"].get<std::string>())!=threaded_actions.end() && !is_threading_allowed) throw std::runtime_error("Multithreaded actions aren't allowed in this module, and so can not be executed from RunActionsIfAction.");
|
|
if (!act.contains("args")) throw std::runtime_error("Action arguments aren't provided.");
|
|
if (!act["args"].is_object()) throw std::runtime_error("Action arguments aren't stored in a dictionnary.");
|
|
actions_else.push_back(act);
|
|
}
|
|
this->condition=args["condition"];
|
|
this->is_threading_allowed=is_threading_allowed;
|
|
this->root_folder=root_folder;
|
|
}
|
|
json condition;
|
|
std::vector<json> actions_if;
|
|
std::vector<json> actions_else;
|
|
bool is_threading_allowed;
|
|
std::string root_folder;
|
|
ActionStatus run_action();
|
|
};
|
|
class RunCommandStrAction {
|
|
public:
|
|
RunCommandStrAction(const json& args) {
|
|
check_arg_string(args,"command");
|
|
if (!args.contains("show_output")) throw std::runtime_error("Show output isn't provided.");
|
|
if (!args["show_output"].is_string()) throw std::runtime_error("Show output isn't a string");
|
|
if (args["show_output"]!="live" && args["show_output"]!="on_failure" && args["show_output"]!="silent") {
|
|
throw std::runtime_error("\""+args["show_output"].get<std::string>()+"\" isn't a valid output mode.");
|
|
}
|
|
if (!args.contains("success_status")) throw std::runtime_error("Success status isn't provided.");
|
|
if (!args["success_status"].is_array()) throw std::runtime_error("Success status isn't a boolean");
|
|
for (auto& arg:args["success_status"]) {
|
|
if (!arg.is_number_integer()) throw std::runtime_error("One of the status code isn't an integer.");
|
|
}
|
|
if (!args.contains("ignore_success_status")) throw std::runtime_error("Ignore success status isn't provided.");
|
|
if (!args["ignore_success_status"].is_boolean()) throw std::runtime_error("Ignore success status isn't a boolean");
|
|
this->command_variables=args["command_variables"].get<bool>();
|
|
this->command=args["command"].get<std::string>();
|
|
this->show_output=args["show_output"].get<std::string>();
|
|
this->success_status=args["success_status"].get<std::vector<int>>();
|
|
this->ignore_success_status=args["ignore_success_status"].get<bool>();
|
|
}
|
|
bool command_variables;
|
|
std::string command;
|
|
std::string show_output;
|
|
std::vector<int> success_status;
|
|
bool ignore_success_status;
|
|
ActionStatus run_action();
|
|
};
|
|
class ComputeElementHashAction {
|
|
public:
|
|
ComputeElementHashAction(const json& args) {
|
|
check_arg_string(args,"element");
|
|
if (!args.contains("output_variable")) throw std::runtime_error("Output variable isn't provided.");
|
|
if (!args["output_variable"].is_string()) throw std::runtime_error("Output variable isn't a string.");
|
|
this->element_variables=args["element_variables"].get<bool>();
|
|
this->element=args["element"].get<std::string>();
|
|
this->output_variable=args["output_variable"].get<std::string>();
|
|
}
|
|
bool element_variables;
|
|
std::string element;
|
|
std::string output_variable;
|
|
ActionStatus run_action();
|
|
};
|
|
class CompileMultipleCppAction {
|
|
public:
|
|
CompileMultipleCppAction(const json& args) {
|
|
check_arg_vector_string(args,"source_files");
|
|
check_arg_string(args,"compiler");
|
|
check_arg_vector_string(args,"pre_arguments");
|
|
check_arg_vector_string(args,"post_arguments");
|
|
check_arg_vector_string(args,"output_files");
|
|
check_arg_string(args,"headers_command");
|
|
if (!args.contains("success_status")) throw std::runtime_error("Success status isn't provided.");
|
|
if (!args["success_status"].is_array()) throw std::runtime_error("Success status isn't a boolean");
|
|
for (auto& arg:args["success_status"]) {
|
|
if (!arg.is_number_integer()) throw std::runtime_error("One of the status code isn't an integer.");
|
|
}
|
|
if (!args.contains("ignore_success_status")) throw std::runtime_error("Ignore success status isn't provided.");
|
|
if (!args["ignore_success_status"].is_boolean()) throw std::runtime_error("Ignore success status isn't a boolean");
|
|
if (!args.contains("cache_authorized")) throw std::runtime_error("Cache authorized isn't provided.");
|
|
if (!args["cache_authorized"].is_boolean()) throw std::runtime_error("Cache authorized isn't a boolean");
|
|
if (!args.contains("source_files_path_completion")) throw std::runtime_error("Source files path completion isn't provided.");
|
|
if (!args["source_files_path_completion"].is_boolean()) throw std::runtime_error("Source files path completion isn't a boolean");
|
|
this->source_files_path_completion=args["source_files_path_completion"].get<bool>();
|
|
if (this->source_files_path_completion) {
|
|
if (!args.contains("path_completion_source_ext")) throw std::runtime_error("Path completion sources extension isn't provided");
|
|
if (!args["path_completion_source_ext"].is_string()) throw std::runtime_error("Path completion sources extension isn't a string");
|
|
if (!args.contains("path_completion_output_ext")) throw std::runtime_error("Path completion output extension isn't provided");
|
|
if (!args["path_completion_output_ext"].is_string()) throw std::runtime_error("Path completion output extension isn't a string");
|
|
this->path_completion_source_ext=args["path_completion_source_ext"].get<std::string>();
|
|
this->path_completion_output_ext=args["path_completion_output_ext"].get<std::string>();
|
|
}
|
|
this->source_files_variables=args["source_files_variables"].get<bool>();
|
|
this->compiler_variables=args["compiler_variables"].get<bool>();
|
|
this->pre_arguments_variables=args["pre_arguments_variables"].get<bool>();
|
|
this->post_arguments_variables=args["post_arguments_variables"].get<bool>();
|
|
this->output_files_variables=args["output_files_variables"].get<bool>();
|
|
this->ignore_success_status=args["ignore_success_status"].get<bool>();
|
|
this->cache_authorized=args["cache_authorized"].get<bool>();
|
|
this->headers_command_variables=args["headers_command_variables"].get<bool>();
|
|
this->compiler=args["compiler"].get<std::string>();
|
|
this->headers_command=args["headers_command"].get<std::string>();
|
|
this->source_files=args["source_files"].get<std::vector<std::string>>();
|
|
this->pre_arguments=args["pre_arguments"].get<std::vector<std::string>>();
|
|
this->post_arguments=args["post_arguments"].get<std::vector<std::string>>();
|
|
this->output_files=args["output_files"].get<std::vector<std::string>>();
|
|
this->success_status=args["success_status"].get<std::vector<int>>();
|
|
}
|
|
bool source_files_path_completion;
|
|
bool source_files_variables;
|
|
std::vector<std::string> source_files;
|
|
bool compiler_variables;
|
|
std::string compiler;
|
|
bool pre_arguments_variables;
|
|
std::vector<std::string> pre_arguments;
|
|
bool post_arguments_variables;
|
|
std::vector<std::string> post_arguments;
|
|
bool output_files_variables;
|
|
std::vector<std::string> output_files;
|
|
std::vector<int> success_status;
|
|
bool ignore_success_status;
|
|
bool cache_authorized;
|
|
bool headers_command_variables;
|
|
std::string headers_command;
|
|
std::string path_completion_source_ext;
|
|
std::string path_completion_output_ext;
|
|
ActionStatus run_action();
|
|
};
|
|
class CopyFileAction {
|
|
public:
|
|
CopyFileAction(const json& args) {
|
|
check_arg_string(args,"source_file");
|
|
check_arg_string(args,"destination_folder");
|
|
this->source_file_variables=args["source_file_variables"].get<bool>();
|
|
this->source_file=args["source_file"].get<std::string>();
|
|
this->destination_folder_variables=args["destination_folder_variables"].get<bool>();
|
|
this->destination_folder=args["destination_folder"].get<std::string>();
|
|
}
|
|
bool source_file_variables;
|
|
std::string source_file;
|
|
bool destination_folder_variables;
|
|
std::string destination_folder;
|
|
ActionStatus run_action();
|
|
};
|
|
class CreateFat32Action {
|
|
public:
|
|
CreateFat32Action(const json& args) {
|
|
check_arg_string(args,"key");
|
|
if (!args.contains("size")) throw std::runtime_error("Size isn't provided.");
|
|
if (!args["size"].is_number_unsigned()) throw std::runtime_error("Size isn't an integer.");
|
|
this->key_variables=args["key_variables"].get<bool>();
|
|
this->key=args["key"].get<std::string>();
|
|
this->size=args["size"].get<size_t>();
|
|
}
|
|
bool key_variables;
|
|
std::string key;
|
|
size_t size;
|
|
ActionStatus run_action();
|
|
};
|
|
class CreateFolderFat32Action {
|
|
public:
|
|
CreateFolderFat32Action(const json& args) {
|
|
check_arg_string(args,"key");
|
|
check_arg_string(args,"full_path");
|
|
this->key_variables=args["key_variables"].get<bool>();
|
|
this->key=args["key"].get<std::string>();
|
|
this->full_path_variables=args["full_path_variables"].get<bool>();
|
|
this->full_path=args["full_path"].get<std::string>();
|
|
}
|
|
bool key_variables;
|
|
std::string key;
|
|
bool full_path_variables;
|
|
std::string full_path;
|
|
ActionStatus run_action();
|
|
};
|
|
class CreateFileFat32Action {
|
|
public:
|
|
CreateFileFat32Action(const json& args) {
|
|
check_arg_string(args,"key");
|
|
check_arg_string(args,"source_path");
|
|
check_arg_string(args,"full_path");
|
|
if (args.contains("is_vftm_target")) {
|
|
if (!args["is_vftm_target"].is_boolean()) throw std::runtime_error("Is VFTM target isn't an boolean.");
|
|
this->is_vftm_target=args["is_vftm_target"].get<bool>();
|
|
}
|
|
this->key_variables=args["key_variables"].get<bool>();
|
|
this->key=args["key"].get<std::string>();
|
|
this->source_path_variables=args["source_path_variables"].get<bool>();
|
|
this->source_path=args["source_path"].get<std::string>();
|
|
this->full_path_variables=args["full_path_variables"].get<bool>();
|
|
this->full_path=args["full_path"].get<std::string>();
|
|
}
|
|
bool is_vftm_target=false;
|
|
bool key_variables;
|
|
std::string key;
|
|
bool source_path_variables;
|
|
std::string source_path;
|
|
bool full_path_variables;
|
|
std::string full_path;
|
|
ActionStatus run_action();
|
|
};
|
|
class ExportFat32Action {
|
|
public:
|
|
ExportFat32Action(const json& args) {
|
|
check_arg_string(args,"key");
|
|
check_arg_string(args,"export_path");
|
|
if (!args.contains("generate_vftm")) throw std::runtime_error("Generate VFTM isn't provided.");
|
|
if (!args["generate_vftm"].is_boolean()) throw std::runtime_error("Generate VFTM isn't a boolean.");
|
|
this->generate_vftm=args["generate_vftm"].get<bool>();
|
|
if (this->generate_vftm) {
|
|
if (!args.contains("disk_guid_var")) throw std::runtime_error("Disk GUID variable must be provided when generate_vftm is true.");
|
|
if (!args["disk_guid_var"].is_string()) throw std::runtime_error("Disk GUID variable must be a string.");
|
|
if (!args.contains("efi_part_unique_guid_var")) throw std::runtime_error("EFI partition unique GUID variable must be provided when generate_vftm is true.");
|
|
if (!args["efi_part_unique_guid_var"].is_string()) throw std::runtime_error("EFI partition unique GUID variable must be a boolean.");
|
|
this->disk_guid_var=args["disk_guid_var"].get<std::string>();
|
|
this->efi_part_unique_guid_var=args["efi_part_unique_guid_var"].get<std::string>();
|
|
}
|
|
this->key_variables=args["key_variables"].get<bool>();
|
|
this->key=args["key"].get<std::string>();
|
|
this->export_path_variables=args["export_path_variables"].get<bool>();
|
|
this->export_path=args["export_path"].get<std::string>();
|
|
}
|
|
bool key_variables;
|
|
std::string key;
|
|
bool export_path_variables;
|
|
std::string export_path;
|
|
bool generate_vftm;
|
|
std::string disk_guid_var;
|
|
std::string efi_part_unique_guid_var;
|
|
ActionStatus run_action();
|
|
};
|
|
class CreateDiskAction {
|
|
public:
|
|
CreateDiskAction(const json& args) {
|
|
check_arg_string(args,"key");
|
|
check_arg_string(args,"disk_guid");
|
|
if (!args.contains("size")) throw std::runtime_error("Size isn't provided.");
|
|
if (!args["size"].is_number_unsigned()) throw std::runtime_error("Size isn't an integer.");
|
|
this->key_variables=args["key_variables"].get<bool>();
|
|
this->key=args["key"].get<std::string>();
|
|
this->disk_guid_variables=args["disk_guid_variables"].get<bool>();
|
|
this->disk_guid=args["disk_guid"].get<std::string>();
|
|
this->size=args["size"].get<size_t>();
|
|
}
|
|
bool key_variables;
|
|
std::string key;
|
|
size_t size;
|
|
bool disk_guid_variables;
|
|
std::string disk_guid;
|
|
ActionStatus run_action();
|
|
};
|
|
class AddPartitionDiskAction {
|
|
public:
|
|
AddPartitionDiskAction(const json& args) {
|
|
check_arg_string(args,"key");
|
|
check_arg_string(args,"type_guid");
|
|
check_arg_string(args,"unique_guid");
|
|
check_arg_string(args,"name");
|
|
check_arg_string(args,"source_file");
|
|
this->key_variables=args["key_variables"].get<bool>();
|
|
this->key=args["key"].get<std::string>();
|
|
this->type_guid_variables=args["type_guid_variables"].get<bool>();
|
|
this->type_guid=args["type_guid"].get<std::string>();
|
|
this->unique_guid_variables=args["unique_guid_variables"].get<bool>();
|
|
this->unique_guid=args["unique_guid"].get<std::string>();
|
|
this->name_variables=args["name_variables"].get<bool>();
|
|
this->name=args["name"].get<std::string>();
|
|
this->source_file_variables=args["source_file_variables"].get<bool>();
|
|
this->source_file=args["source_file"].get<std::string>();
|
|
}
|
|
bool key_variables;
|
|
std::string key;
|
|
bool type_guid_variables;
|
|
std::string type_guid;
|
|
bool unique_guid_variables;
|
|
std::string unique_guid;
|
|
bool name_variables;
|
|
std::string name;
|
|
bool source_file_variables;
|
|
std::string source_file;
|
|
ActionStatus run_action();
|
|
};
|
|
class ExportDiskAction {
|
|
public:
|
|
ExportDiskAction(const json& args) {
|
|
check_arg_string(args,"key");
|
|
check_arg_string(args,"export_path");
|
|
this->key_variables=args["key_variables"].get<bool>();
|
|
this->key=args["key"].get<std::string>();
|
|
this->export_path_variables=args["export_path_variables"].get<bool>();
|
|
this->export_path=args["export_path"].get<std::string>();
|
|
}
|
|
bool key_variables;
|
|
std::string key;
|
|
bool export_path_variables;
|
|
std::string export_path;
|
|
ActionStatus run_action();
|
|
};
|
|
class VFTMLoadCryptoLibAction {
|
|
public:
|
|
VFTMLoadCryptoLibAction(const json& args) {
|
|
check_arg_string(args,"lib_path");
|
|
this->lib_path_variables=args["lib_path_variables"].get<bool>();
|
|
this->lib_path=args["lib_path"].get<std::string>();
|
|
}
|
|
bool lib_path_variables;
|
|
std::string lib_path;
|
|
ActionStatus run_action();
|
|
};
|
|
class VFTMRunKeysGeneratorAction {
|
|
public:
|
|
VFTMRunKeysGeneratorAction(const json& args) {
|
|
check_arg_vector_string(args,"command");
|
|
check_arg_string(args,"working_dir");
|
|
check_arg_string(args,"socket_path");
|
|
if (!args.contains("success_status")) throw std::runtime_error("Success status isn't provided.");
|
|
if (!args["success_status"].is_array()) throw std::runtime_error("Success status isn't a boolean");
|
|
for (auto& arg:args["success_status"]) {
|
|
if (!arg.is_number_integer()) throw std::runtime_error("One of the status code isn't an integer.");
|
|
}
|
|
if (!args.contains("ignore_success_status")) throw std::runtime_error("Ignore success status isn't provided.");
|
|
if (!args["ignore_success_status"].is_boolean()) throw std::runtime_error("Ignore success status isn't a boolean");
|
|
this->command_variables=args["command_variables"].get<bool>();
|
|
this->command=args["command"].get<std::vector<std::string>>();
|
|
this->socket_path_variables=args["socket_path_variables"].get<bool>();
|
|
this->socket_path=args["socket_path"].get<std::string>();
|
|
this->success_status=args["success_status"].get<std::vector<int>>();
|
|
this->ignore_success_status=args["ignore_success_status"].get<bool>();
|
|
this->working_dir_variables=args["working_dir_variables"].get<bool>();
|
|
this->working_dir=args["working_dir"].get<std::string>();
|
|
}
|
|
bool command_variables;
|
|
std::vector<std::string> command;
|
|
bool socket_path_variables;
|
|
std::string socket_path;
|
|
std::vector<int> success_status;
|
|
bool ignore_success_status;
|
|
bool working_dir_variables;
|
|
std::string working_dir;
|
|
ActionStatus run_action();
|
|
};
|
|
using ParallelAction=std::variant<RunCommandWaitAction,
|
|
SaveCommandContentAction,
|
|
CompileOneAsmAction,
|
|
EnsureFolderExistenceAction,
|
|
MoveFileAction,
|
|
CompileOneCppAction,
|
|
RunCommandWaitDirAction,
|
|
CopyFolderAction,
|
|
ExtractFromCacheAction,
|
|
StoreInCacheAction,
|
|
EnsureFolderResetAction,
|
|
RunActionsIfAction,
|
|
RunCommandStrAction,
|
|
RunActionsIfElseAction,
|
|
ComputeElementHashAction,
|
|
CopyFileAction,
|
|
CreateFat32Action,
|
|
CreateFolderFat32Action,
|
|
CreateFileFat32Action,
|
|
ExportFat32Action,
|
|
CreateDiskAction,
|
|
AddPartitionDiskAction,
|
|
ExportDiskAction,
|
|
VFTMLoadCryptoLibAction,
|
|
VFTMRunKeysGeneratorAction>;
|
|
ParallelAction return_pararrel_action(const json& args,std::string action_name);
|
|
class RunActionsParallelAction {
|
|
public:
|
|
RunActionsParallelAction (const json& args) {
|
|
if (!args.contains("actions")) throw std::runtime_error("No actions are provided.");
|
|
if (!args["actions"].is_array()) throw std::runtime_error("Provided actions aren't stored in a list.");
|
|
for (const auto& act:args["actions"]) {
|
|
if (!act.is_object()) throw std::runtime_error("One of the action isn't a dictionnary.");
|
|
if (!act.contains("action")) throw std::runtime_error("Action isn't provided.");
|
|
if (!act["action"].is_string()) throw std::runtime_error("Action isn't a string.");
|
|
if (!act.contains("args")) throw std::runtime_error("Action arguments aren't provided.");
|
|
if (!act["args"].is_object()) throw std::runtime_error("Action arguments aren't stored in a dictionnary.");
|
|
actions.push_back(return_pararrel_action(act["args"],act["action"]));
|
|
}
|
|
}
|
|
std::vector<ParallelAction> actions;
|
|
ActionStatus run_action();
|
|
};
|
|
class RunSubmoduleParallelAction {
|
|
public:
|
|
RunSubmoduleParallelAction(const json& args) {
|
|
check_arg_vector_string(args,"submodules");
|
|
for (const auto& act:args["submodules"]) {
|
|
submodules.push_back(act.get<std::string>());
|
|
}
|
|
this->submodules_variables=args["submodules_variables"].get<bool>();
|
|
}
|
|
bool submodules_variables;
|
|
std::vector<std::string> submodules;
|
|
ActionStatus run_action();
|
|
};
|
|
class VyldCompilationAction {
|
|
public:
|
|
VyldCompilationAction(const json& args) {
|
|
check_arg_vector_string(args,"source_files");
|
|
check_arg_vector_string(args,"source_asm");
|
|
check_arg_string(args,"compiler");
|
|
check_arg_string(args,"assembler");
|
|
check_arg_string(args,"linker");
|
|
check_arg_string(args,"compiler_flags");
|
|
check_arg_string(args,"output_file");
|
|
check_arg_string(args,"headers_command");
|
|
if (!args.contains("source_files_path_completion")) throw std::runtime_error("Source file path completion isn't provided.");
|
|
if (!args["source_files_path_completion"].is_boolean()) throw std::runtime_error("Source file path completion isn't a boolean.");
|
|
if (!args.contains("source_asm_path_completion")) throw std::runtime_error("Source ASM path completion isn't provided.");
|
|
if (!args["source_asm_path_completion"].is_boolean()) throw std::runtime_error("Source ASM path completion isn't a boolean.");
|
|
if (!args.contains("block_if_fail")) throw std::runtime_error("Block if fail isn't provided.");
|
|
if (!args["block_if_fail"].is_boolean()) throw std::runtime_error("Block if fail isn't a boolean.");
|
|
if (!args.contains("object_files_cache_authorized")) throw std::runtime_error("Object files caching authorized isn't provided.");
|
|
if (!args["object_files_cache_authorized"].is_boolean()) throw std::runtime_error("Object files caching authorized isn't a boolean.");
|
|
if (!args.contains("payloads")) throw std::runtime_error("Payloads aren't provided.");
|
|
if (!args["payloads"].is_array()) throw std::runtime_error("Payloads aren't stored in a list.");
|
|
this->source_files_path_completion=args["source_files_path_completion"].get<bool>();
|
|
this->source_asm_path_completion=args["source_asm_path_completion"].get<bool>();
|
|
this->source_files_variables=args["source_files_variables"].get<bool>();
|
|
this->source_asm_variables=args["source_asm_variables"].get<bool>();
|
|
this->compiler_variables=args["compiler_variables"].get<bool>();
|
|
this->assembler_variables=args["assembler_variables"].get<bool>();
|
|
this->linker_variables=args["linker_variables"].get<bool>();
|
|
this->compiler_flags_variables=args["compiler_flags_variables"].get<bool>();
|
|
this->output_file_variables=args["output_file_variables"].get<bool>();
|
|
this->block_if_fail=args["block_if_fail"].get<bool>();
|
|
this->object_files_cache_authorized=args["object_files_cache_authorized"].get<bool>();
|
|
this->headers_command_variables=args["headers_command_variables"].get<bool>();
|
|
this->source_files=args["source_files"].get<std::vector<std::string>>();
|
|
this->source_asm=args["source_asm"].get<std::vector<std::string>>();
|
|
this->compiler=args["compiler"].get<std::string>();
|
|
this->assembler=args["assembler"].get<std::string>();
|
|
this->linker=args["linker"].get<std::string>();
|
|
this->compiler_flags=args["compiler_flags"].get<std::string>();
|
|
this->output_file=args["output_file"].get<std::string>();
|
|
this->headers_command=args["headers_command"].get<std::string>();
|
|
this->payloads=args["payloads"].get<std::vector<json>>();
|
|
}
|
|
bool source_files_path_completion;
|
|
bool source_files_variables;
|
|
std::vector<std::string> source_files;
|
|
bool compiler_variables;
|
|
std::string compiler;
|
|
bool source_asm_path_completion;
|
|
bool source_asm_variables;
|
|
std::vector<std::string> source_asm;
|
|
bool assembler_variables;
|
|
std::string assembler;
|
|
bool linker_variables;
|
|
std::string linker;
|
|
bool compiler_flags_variables;
|
|
std::string compiler_flags;
|
|
bool output_file_variables;
|
|
std::string output_file;
|
|
bool block_if_fail;
|
|
bool object_files_cache_authorized;
|
|
bool headers_command_variables;
|
|
std::string headers_command;
|
|
std::vector<json> payloads;
|
|
ActionStatus run_action();
|
|
};
|
|
using Action=std::variant<RunSubmoduleAction,
|
|
RunCommandWaitAction,
|
|
RunActionsParallelAction,
|
|
SaveCommandContentAction,
|
|
CompileOneAsmAction,
|
|
EnsureFolderExistenceAction,
|
|
MoveFileAction,
|
|
CompileOneCppAction,
|
|
VyldCompilationAction,
|
|
RunSubmoduleIfAction,
|
|
RunCommandWaitDirAction,
|
|
CopyFolderAction,
|
|
RunSubmoduleParallelAction,
|
|
ExtractFromCacheAction,
|
|
StoreInCacheAction,
|
|
EnsureFolderResetAction,
|
|
RunActionsIfAction,
|
|
RunCommandStrAction,
|
|
RunActionsIfElseAction,
|
|
ComputeElementHashAction,
|
|
CompileMultipleCppAction,
|
|
CopyFileAction,
|
|
CreateFat32Action,
|
|
CreateFolderFat32Action,
|
|
CreateFileFat32Action,
|
|
ExportFat32Action,
|
|
CreateDiskAction,
|
|
AddPartitionDiskAction,
|
|
ExportDiskAction,
|
|
VFTMLoadCryptoLibAction,
|
|
VFTMRunKeysGeneratorAction>;
|
|
Action return_action(const json &args,std::string action_name,bool is_threading_allowed,std::string root_folder);
|
|
}
|
|
namespace module {
|
|
class Module {
|
|
public:
|
|
Module(std::string file,bool is_threading_allowed) {
|
|
std::ifstream f(file);
|
|
if (!f) {
|
|
throw std::runtime_error(file+" couldn't be opened.");
|
|
}
|
|
json j=json::parse(f);
|
|
if (!j.contains("version")) throw std::runtime_error("Syntax version isn't provided.");
|
|
if (!j["version"].is_string()) throw std::runtime_error("Syntax version isn't a string.");
|
|
if (j["version"]!=syntax_version) throw std::runtime_error("Syntax version is "+j["version"].get<std::string>()+". Expected "+syntax_version+".");
|
|
if (j.contains("root_folder")) {
|
|
if (!j["root_folder"].is_string()) throw std::runtime_error("Root folder isn't a string.");
|
|
this->root_folder=vybuild::parser::root_folder_parsing(j["root_folder"].get<std::string>(),file);
|
|
} else {
|
|
this->root_folder=vybuild::parser::root_folder_parsing("%filefolder%",file);
|
|
}
|
|
if (!j.contains("run_context")) throw std::runtime_error("Run context isn't provided.");
|
|
if (!j["run_context"].is_string()) throw std::runtime_error("Run context isn't a string.");
|
|
if (j["run_context"]!="root" && j["run_context"]!="sub" && j["run_context"]!="both") throw std::runtime_error("\""+j["run_context"].get<std::string>()+"\" isn't a string.");
|
|
this->run_context=j["run_context"].get<std::string>();
|
|
if (!j.contains("name")) throw std::runtime_error("Name isn't provided.");
|
|
if (!j["name"].is_string()) throw std::runtime_error("Name isn't a string.");
|
|
this->name=j["name"].get<std::string>();
|
|
if (this->run_context=="root" && j.contains("global_vars")) {
|
|
if (!j["global_vars"].is_object()) throw std::runtime_error("Global variables aren't in a list.");
|
|
for (const auto& [var_name,value]:j["global_vars"].items()) {
|
|
vybuild::vars::set_global_variable("\\$"+var_name+"\\$",value);
|
|
}
|
|
} else if (this->run_context!="root" && j.contains("global_vars")){
|
|
throw std::runtime_error("Global variables are only available for modules that are guaranteed to be runned as root.");
|
|
}
|
|
if (this->run_context=="root" && j.contains("global_uuid")) {
|
|
if (!j["global_uuid"].is_array()) throw std::runtime_error("Global UUID aren't in a list.");
|
|
for (const auto& var_name:j["global_uuid"].items()) {
|
|
uuid_t id;
|
|
uuid_generate_random(id);
|
|
char out[37];
|
|
uuid_unparse_lower(id,out);
|
|
vybuild::vars::set_global_variable("\\$"+var_name.value().get<std::string>()+"\\$",std::string(out));
|
|
}
|
|
} else if (this->run_context!="root" && j.contains("global_uuid")){
|
|
throw std::runtime_error("Global UUID are only available for modules that are guaranteed to be runned as root.");
|
|
}
|
|
if (!j.contains("actions")) throw std::runtime_error("Couldn't find any action inside module.");
|
|
if (!j["actions"].is_array()) throw std::runtime_error("Actions aren't in a list.");
|
|
for (const auto& act:j["actions"]) {
|
|
if (!act.is_object()) throw std::runtime_error("One of the action isn't a dictionnary.");
|
|
if (!act.contains("action")) throw std::runtime_error("Action isn't provided.");
|
|
if (!act["action"].is_string()) throw std::runtime_error("Action isn't a string.");
|
|
if (!act.contains("args")) throw std::runtime_error("Action arguments aren't provided.");
|
|
if (!act["args"].is_object()) throw std::runtime_error("Action arguments aren't stored in a dictionnary.");
|
|
actions.push_back(vybuild::actions::return_action(act["args"],act["action"],is_threading_allowed,this->root_folder));
|
|
}
|
|
}
|
|
std::string root_folder;
|
|
std::string run_context;
|
|
std::string name;
|
|
std::vector<vybuild::actions::Action> actions;
|
|
vybuild::actions::ActionStatus run_module(bool is_root,bool is_threaded) {
|
|
if (this->run_context=="root" && !is_root) {
|
|
throw std::runtime_error("Module isn't supposed to be ran as a submodule.");
|
|
} else if (this->run_context=="sub" && is_root) {
|
|
throw std::runtime_error("Module isn't supposed to be ran as root module.");
|
|
}
|
|
if (is_threaded) unshare(CLONE_FS);
|
|
char path[PATH_MAX];
|
|
getcwd(path,sizeof(path));
|
|
chdir(this->root_folder.c_str());
|
|
for (auto& a:actions) {
|
|
vybuild::actions::ActionStatus status=std::visit([](auto& act) {
|
|
return act.run_action();
|
|
},a);
|
|
if (status!=vybuild::actions::ActionStatus::Success && status!=vybuild::actions::ActionStatus::ExitSuccess) {
|
|
chdir(path);
|
|
return status;
|
|
}
|
|
if (status==vybuild::actions::ActionStatus::ExitSuccess) {
|
|
chdir(path);
|
|
return vybuild::actions::ActionStatus::Success;
|
|
}
|
|
}
|
|
chdir(path);
|
|
return vybuild::actions::ActionStatus::Success;
|
|
}
|
|
};
|
|
}
|
|
}
|
|
#endif
|