Execute commands defined in apps.json
This commit is contained in:
@@ -6,6 +6,9 @@
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
#include <boost/property_tree/json_parser.hpp>
|
||||
|
||||
#include "process.h"
|
||||
#include "config.h"
|
||||
#include "utility.h"
|
||||
@@ -14,6 +17,9 @@
|
||||
namespace proc {
|
||||
using namespace std::literals;
|
||||
namespace bp = boost::process;
|
||||
namespace pt = boost::property_tree;
|
||||
|
||||
proc_t proc;
|
||||
|
||||
template<class Rep, class Period>
|
||||
void process_end(bp::child &proc, const std::chrono::duration<Rep, Period>& rel_time) {
|
||||
@@ -21,10 +27,12 @@ void process_end(bp::child &proc, const std::chrono::duration<Rep, Period>& rel_
|
||||
return;
|
||||
}
|
||||
|
||||
platf::interrupt_process((std::uint64_t)proc.native_handle());
|
||||
std::cout << "Interruping Child-Process"sv << std::endl;
|
||||
platf::terminate_process((std::uint64_t) proc.native_handle());
|
||||
|
||||
// Force termination if it takes too long
|
||||
if(!proc.wait_for(rel_time)) {
|
||||
std::cout << "Force termination Child-Process"sv << std::endl;
|
||||
proc.terminate();
|
||||
}
|
||||
}
|
||||
@@ -40,8 +48,10 @@ int exe(const std::string &cmd, bp::environment &env, file_t &file, std::error_c
|
||||
int proc_t::execute(const std::string &name) {
|
||||
auto it = _name_to_proc.find(name);
|
||||
|
||||
std::cout << "Ensure clean slate"sv << std::endl;
|
||||
// Ensure starting from a clean slate
|
||||
_undo_pre_cmd();
|
||||
std::cout << "Clean slate"sv << std::endl;
|
||||
|
||||
if(it == std::end(_name_to_proc)) {
|
||||
std::cout << "Error: Couldn't find ["sv << name << ']' << std::endl;
|
||||
@@ -137,7 +147,79 @@ void proc_t::_undo_pre_cmd() {
|
||||
|
||||
_pipe.reset();
|
||||
}
|
||||
|
||||
const std::unordered_map<std::string, ctx_t> &proc_t::get_apps() const {
|
||||
return _name_to_proc;
|
||||
}
|
||||
|
||||
proc_t::~proc_t() {
|
||||
_undo_pre_cmd();
|
||||
}
|
||||
|
||||
std::optional<proc::proc_t> parse(const std::string& file_name) {
|
||||
pt::ptree tree;
|
||||
|
||||
try {
|
||||
pt::read_json(file_name, tree);
|
||||
|
||||
auto &apps_node = tree.get_child("apps"s);
|
||||
auto &env_vars = tree.get_child("env"s);
|
||||
|
||||
boost::process::environment env = boost::this_process::environment();
|
||||
|
||||
std::unordered_map<std::string, proc::ctx_t> apps;
|
||||
for(auto &[_,app_node] : apps_node) {
|
||||
proc::ctx_t ctx;
|
||||
|
||||
auto &prep_nodes = app_node.get_child("prep-cmd"s);
|
||||
auto name = app_node.get<std::string>("name"s);
|
||||
auto output = app_node.get_optional<std::string>("output"s);
|
||||
auto cmd = app_node.get<std::string>("cmd"s);
|
||||
|
||||
std::vector<proc::cmd_t> prep_cmds;
|
||||
prep_cmds.reserve(prep_nodes.size());
|
||||
for(auto &[_, prep_node] : prep_nodes) {
|
||||
auto do_cmd = prep_node.get<std::string>("do"s);
|
||||
auto undo_cmd = prep_node.get_optional<std::string>("undo"s);
|
||||
|
||||
if(undo_cmd) {
|
||||
prep_cmds.emplace_back(std::move(do_cmd), std::move(*undo_cmd));
|
||||
}
|
||||
else {
|
||||
prep_cmds.emplace_back(std::move(do_cmd));
|
||||
}
|
||||
}
|
||||
|
||||
if(output) {
|
||||
ctx.output = std::move(*output);
|
||||
}
|
||||
ctx.cmd = std::move(cmd);
|
||||
ctx.prep_cmds = std::move(prep_cmds);
|
||||
|
||||
apps.emplace(std::move(name), std::move(ctx));
|
||||
}
|
||||
|
||||
for(auto &[_,env_var] : env_vars) {
|
||||
for(auto &[name,val] : env_var) {
|
||||
env[name] = val.get_value<std::string>();
|
||||
}
|
||||
}
|
||||
|
||||
return proc::proc_t {
|
||||
std::move(env), std::move(apps)
|
||||
};
|
||||
} catch (std::exception &e) {
|
||||
std::cout << e.what() << std::endl;
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
void refresh(const std::string &file_name) {
|
||||
auto proc_opt = proc::parse(file_name);
|
||||
|
||||
if(proc_opt) {
|
||||
proc = std::move(*proc_opt);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user