container: root: add plugins support

- Implements support for docker-finance C++ plugins
- Adds shell command execution wrapper
- Refactors previous loader path
  * A './' path is unnecessary and will break calls to '/' path
This commit is contained in:
2024-08-10 18:50:06 -07:00
parent f967faeb8a
commit 6e250c7282
2 changed files with 113 additions and 2 deletions

View File

@@ -72,7 +72,7 @@ class Command final
//! \brief Load given file path
static void load(const std::string& path)
{
std::string cmd{".L ./" + path};
std::string cmd{".L " + path};
Command::cmd_handler({cmd});
}
@@ -97,6 +97,15 @@ std::string get_env(const std::string& var)
return std::string{env};
}
//! \brief Execute command in shell
//! \param cmd Shell command [args]
//! \returns Return value of command
//! \since docker-finance 1.0.0
int exec(const std::string& cmd)
{
return gSystem->Exec(cmd.c_str());
}
//! \brief Make current timestamp
//! \return timestamp in "yyyy-mm-ddThh:mm:ssZ" format
//! \since docker-finance 1.0.0
@@ -140,6 +149,84 @@ void load(const std::initializer_list<std::string>& paths)
common::Command::load(path);
}
} // namespace macro
//! \namespace docker_finance::plugin
//! \brief docker-finance plugins
//! \warning All plugins (repo/custom) must exist within this namespace
//! and work within their own inner namespace
//! \since docker-finance 1.0.0
namespace plugin
{
//! \brief Load plugin by pseudo-paths
//! \details Wrapper to load from directory outside of default tree
//! \param path Must be of string "repo/file" or "custom/file" where file is
//! a plugin filename that exists in repository plugin path or
//! a client-side end-user's custom plugin path.
//! \ingroup cpp_plugin
//! \details
//! Example:
//! <br>&emsp; root [0] docker_finance::plugin::load("repo/example.cc")<br>
//!
//! Will load:
//! <br>&emsp; ${DOCKER_FINANCE_CONTAINER_REPO}/plugins/root/example.cc<br>
//!
//! Example:
//! <br>&emsp; root [0] docker_finance::plugin::load("custom/example.cc")<br>
//!
//! Will load:
//! <br>&emsp; ${DOCKER_FINANCE_CLIENT_PLUGINS}/root/example.cc<br>
//!
//! \note Parent directory for all plugins are outside of repository's `root` directory
void load(const std::string& path)
{
const std::string type{path.substr(0, path.find("/"))};
std::string file{path};
file.erase(0, file.find("/") + 1);
if (type == "repo")
{
file.insert(
0,
macro::common::get_env("DOCKER_FINANCE_CONTAINER_REPO")
+ "/plugins/root/");
}
else if (type == "custom")
{
file.insert(
0,
macro::common::get_env("DOCKER_FINANCE_CONTAINER_PLUGINS")
+ "/root/");
}
else
{
throw std::runtime_error(
"must be of type 'repo/<file>' or 'custom/<file>'");
}
macro::common::Command::load(file);
}
//! \brief Wrapper to load plugins by list of pseudo-paths
//! \ingroup cpp_plugin
//! \param paths List must consist of string "repo/file" or "custom/file" where file is
//! a plugin filename that exists in repository plugin path or
//! a client-side end-user's custom plugin path.
//! \details
//! Example:
//! <br>&emsp; root [0] docker_finance::plugin::load({"repo/example.cc", "custom/example.cc"})<br>
//!
//! Will load:
//! <br>&emsp; ${DOCKER_FINANCE_CONTAINER_REPO}/plugins/root/example.cc
//! and ${DOCKER_FINANCE_CLIENT_PLUGINS}/root/example.cc<br>
//!
//! \note Parent directory for all plugins are outside of repository's `root` directory
void load(const std::initializer_list<std::string>& paths)
{
for (const auto& path : paths)
macro::common::Command::load(path);
}
} // namespace plugin
} // namespace docker_finance
#endif // CONTAINER_SRC_ROOT_MACRO_COMMON_UTILITY_HH_

View File

@@ -46,6 +46,8 @@ void help()
<< "\n"
<< " docker-finance C++ interpretations / interactive calculations\n"
<< "\n"
<< " *** TIP: save your fingers! Use tab completion! ***\n"
<< "\n"
<< " 1. Print current directory (all commands/files are relative to\n"
<< " this directory):\n"
<< "\n"
@@ -101,9 +103,31 @@ void help()
<< " Maximum = 1.00000077\n"
<< " Printed = 1.00000077\n"
<< "\n"
<< "Plugins:\n"
<< "\n"
<< " WARNING: unlike macro loader, the prepended 'repo' and 'custom'\n"
<< " are not real directories but rather indications that the file\n"
<< " is either a repository plugin or an non-repo (custom) plugin.\n"
<< "\n"
<< " 1. Connect to docker-finance API via plugins:\n"
<< "\n"
<< " // Load and run an example repository plugin\n"
<< " root [0] docker_finance::plugin::load(\"repo/example.cc\");\n"
<< " root [1] "
"docker_finance::plugin::my_plugin_namespace::example1();\n"
<< " root [2] "
"docker_finance::plugin::my_plugin_namespace::example2();\n"
<< " root [3] "
"docker_finance::plugin::my_plugin_namespace::example3();\n"
<< "\n"
<< " // Load and run your own custom plugin\n"
<< " root [4] docker_finance::plugin::load(\"custom/example.cc\");\n"
<< " root [5] "
"docker_finance::plugin::your_plugin_namespace::example();\n"
<< "\n"
<< "Macros:\n"
<< "\n"
<< " TIP: use tab auto-complete to easily run macros\n"
<< " NOTE: the macro loader interprets from base 'macro' path (.!pwd)\n"
<< "\n"
<< " 1. Load and run docker-finance unit tests and benchmarks:\n"
<< "\n"