container: root: new pluggable framework
- Implements pluggable auto-(un|re)loading - Refactors, adds/updates documentation
This commit is contained in:
@@ -25,6 +25,7 @@
|
||||
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
//! \namespace dfi
|
||||
//! \since docker-finance 1.0.0
|
||||
@@ -96,6 +97,227 @@ struct InvalidArgument final : public Exception
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//! \brief Data type of underlying operating system locations for pluggable pseudo-paths
|
||||
//! \todo C++23 concept pair-like
|
||||
//! \since docker-finance 1.1.0
|
||||
class PluggablePath
|
||||
{
|
||||
using t_pair = std::pair<std::string, std::string>;
|
||||
|
||||
public:
|
||||
//! \brief Construct with {repository, custom} pluggable directory locations
|
||||
//! \param pair An object where the first element is the repository
|
||||
//! absolute directory path and the second element is the custom
|
||||
//! absolute directory path.
|
||||
explicit PluggablePath(const t_pair& pair) : m_pair(pair) {}
|
||||
~PluggablePath() = default;
|
||||
|
||||
PluggablePath(const PluggablePath&) = default;
|
||||
PluggablePath& operator=(const PluggablePath&) = default;
|
||||
|
||||
PluggablePath(PluggablePath&&) = default;
|
||||
PluggablePath& operator=(PluggablePath&&) = default;
|
||||
|
||||
public:
|
||||
//! \brief Set operating system path to repository pluggable
|
||||
//! \return NPI reference
|
||||
auto& repo(const std::string& arg)
|
||||
{
|
||||
m_pair.first = arg;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \brief Set operating system path to custom pluggable
|
||||
//! \return NPI reference
|
||||
auto& custom(const std::string& arg)
|
||||
{
|
||||
m_pair.second = arg;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \return Operating system path to repository pluggable
|
||||
const std::string& repo() const { return m_pair.first; }
|
||||
|
||||
//! \return Operating system path to custom pluggable
|
||||
const std::string& custom() const { return m_pair.second; }
|
||||
|
||||
private:
|
||||
t_pair m_pair;
|
||||
};
|
||||
|
||||
//! \brief Data type for the pluggable's namespace
|
||||
//! \todo C++23 concept pair-like
|
||||
//! \since docker-finance 1.1.0
|
||||
class PluggableSpace
|
||||
{
|
||||
using t_pair = std::pair<std::string, std::string>;
|
||||
|
||||
public:
|
||||
//! \brief Construct data type with most-outer and inner namespaces
|
||||
explicit PluggableSpace(const t_pair& pair) : m_pair(pair) {}
|
||||
~PluggableSpace() = default;
|
||||
|
||||
PluggableSpace(const PluggableSpace&) = default;
|
||||
PluggableSpace& operator=(const PluggableSpace&) = default;
|
||||
|
||||
PluggableSpace(PluggableSpace&&) = default;
|
||||
PluggableSpace& operator=(PluggableSpace&&) = default;
|
||||
|
||||
public:
|
||||
//! \brief Set pluggable's most-outer namespace
|
||||
//! \return NPI reference
|
||||
auto& outer(const std::string& arg)
|
||||
{
|
||||
m_pair.first = arg;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \brief Set pluggable's inner namespace(s)
|
||||
//! \return NPI reference
|
||||
auto& inner(const std::string& arg)
|
||||
{
|
||||
m_pair.second = arg;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \return Pluggable's most-outer namespace
|
||||
const std::string& outer() const { return m_pair.first; }
|
||||
|
||||
//! \return Pluggable's inner namespace(s)
|
||||
const std::string& inner() const { return m_pair.second; }
|
||||
|
||||
private:
|
||||
t_pair m_pair;
|
||||
};
|
||||
|
||||
//! \brief Data type for pluggable auto-(un)loader arguments
|
||||
//! \todo C++23 concept pair-like
|
||||
//! \since docker-finance 1.1.0
|
||||
class PluggableArgs
|
||||
{
|
||||
using t_pair = std::pair<std::string, std::string>;
|
||||
|
||||
public:
|
||||
//! \brief Construct data type with load/unload arguments
|
||||
explicit PluggableArgs(const t_pair& pair) : m_pair(pair) {}
|
||||
~PluggableArgs() = default;
|
||||
|
||||
PluggableArgs(const PluggableArgs&) = default;
|
||||
PluggableArgs& operator=(const PluggableArgs&) = default;
|
||||
|
||||
PluggableArgs(PluggableArgs&&) = default;
|
||||
PluggableArgs& operator=(PluggableArgs&&) = default;
|
||||
|
||||
public:
|
||||
//! \brief Set pluggable loader argument
|
||||
//! \return NPI reference
|
||||
auto& load(const std::string& arg)
|
||||
{
|
||||
m_pair.first = arg;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \brief Set pluggable unloader argument
|
||||
//! \return NPI reference
|
||||
auto& unload(const std::string& arg)
|
||||
{
|
||||
m_pair.second = arg;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \return Pluggable loader argument
|
||||
const std::string& load() const { return m_pair.first; }
|
||||
|
||||
//! \return Pluggable unloader argument
|
||||
const std::string& unload() const { return m_pair.second; }
|
||||
|
||||
private:
|
||||
t_pair m_pair;
|
||||
};
|
||||
|
||||
//! \concept dfi::common::type::PPath
|
||||
//! \brief Pluggable constrained data type (PluggablePath)
|
||||
//! \ref dfi::common::type::PluggablePath
|
||||
//! \since docker-finance 1.1.0
|
||||
template <typename t_path>
|
||||
concept PPath = requires(t_path path, PluggablePath plug) {
|
||||
path.operator()().operator=(plug);
|
||||
path.operator()().repo("").custom("");
|
||||
path.operator()().repo();
|
||||
path.operator()().custom();
|
||||
};
|
||||
|
||||
//! \concept dfi::common::type::PSpace
|
||||
//! \brief Pluggable constrained data type (PluggableSpace)
|
||||
//! \ref dfi::common::type::PluggableSpace
|
||||
//! \since docker-finance 1.1.0
|
||||
template <typename t_space>
|
||||
concept PSpace = requires(t_space space, PluggableSpace plug) {
|
||||
space.operator()().operator=(plug);
|
||||
space.operator()().outer("").inner("");
|
||||
space.operator()().outer();
|
||||
space.operator()().inner();
|
||||
};
|
||||
|
||||
//! \concept dfi::common::type::PArgs
|
||||
//! \brief Pluggable constrained data type (PluggableArgs)
|
||||
//! \ref dfi::common::type::PluggableArgs
|
||||
//! \since docker-finance 1.1.0
|
||||
template <typename t_args>
|
||||
concept PArgs = requires(t_args args, PluggableArgs plug) {
|
||||
args.operator()().operator=(plug);
|
||||
args.operator()().load("").unload("");
|
||||
args.operator()().load();
|
||||
args.operator()().unload();
|
||||
};
|
||||
|
||||
//! \brief Data type for pluggable handler
|
||||
//! \since docker-finance 1.1.0
|
||||
template <PPath t_path, PSpace t_space, PArgs t_args>
|
||||
class Pluggable
|
||||
{
|
||||
public:
|
||||
explicit Pluggable(
|
||||
const t_path& path,
|
||||
const t_space& space,
|
||||
const t_args& args)
|
||||
: m_path(path), m_space(space), m_args(args)
|
||||
{
|
||||
}
|
||||
~Pluggable() = default;
|
||||
|
||||
Pluggable(const Pluggable&) = default;
|
||||
Pluggable& operator=(const Pluggable&) = default;
|
||||
|
||||
Pluggable(Pluggable&&) = default;
|
||||
Pluggable& operator=(Pluggable&&) = default;
|
||||
|
||||
public:
|
||||
//! \brief Mutator to underlying path type
|
||||
t_path& path() { return m_path; }
|
||||
|
||||
//! \brief Mutator to underlying space type
|
||||
t_space& space() { return m_space; }
|
||||
|
||||
//! \brief Mutator to underlying args type
|
||||
t_args& args() { return m_args; }
|
||||
|
||||
public:
|
||||
//! \brief Accessor to underlying path type
|
||||
const t_path& path() const { return m_path; }
|
||||
|
||||
//! \brief Accessor to underlying space type
|
||||
const t_space& space() const { return m_space; }
|
||||
|
||||
//! \brief Accessor to underlying args type
|
||||
const t_args& args() const { return m_args; }
|
||||
|
||||
private:
|
||||
t_path m_path;
|
||||
t_space m_space;
|
||||
t_args m_args;
|
||||
};
|
||||
} // namespace type
|
||||
} // namespace common
|
||||
} // namespace dfi
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "./type.hh"
|
||||
@@ -273,6 +274,305 @@ std::string make_timestamp()
|
||||
std::strftime(time.data(), time.size(), "%FT%TZ", std::gmtime(&t));
|
||||
return std::string{time.data()};
|
||||
}
|
||||
|
||||
//! \brief Base pseudo-path handler for various pluggables (plugins and macros)
|
||||
//!
|
||||
//! \details Handles pluggable paths, typically used by pluggable
|
||||
//! implementations when auto-(un|re)loading.
|
||||
//!
|
||||
//! \ingroup cpp_plugin_impl cpp_macro_impl
|
||||
//! \since docker-finance 1.1.0
|
||||
class PluggablePath
|
||||
{
|
||||
public:
|
||||
//! \brief Parses (or re-parses) constructed types
|
||||
//! \warning Only call this function after constructing if underlying type::PluggablePath has been changed (post-construction)
|
||||
//! \return NPI reference
|
||||
auto& parse()
|
||||
{
|
||||
// Parse out pseudo tag
|
||||
const std::string type{m_pseudo.substr(0, m_pseudo.find('/'))};
|
||||
|
||||
std::string pruned{m_pseudo};
|
||||
pruned.erase(0, pruned.find('/') + 1);
|
||||
|
||||
// Set family group
|
||||
m_family = pruned;
|
||||
|
||||
// Set parent directory
|
||||
m_parent = pruned.substr(0, pruned.find('/'));
|
||||
|
||||
// Set child (filename)
|
||||
m_child = pruned.substr(pruned.find_last_of('/') + 1);
|
||||
|
||||
// Set absolute path
|
||||
std::string absolute{pruned};
|
||||
if (type == "repo")
|
||||
{
|
||||
m_is_repo = true;
|
||||
absolute.insert(0, m_path.repo());
|
||||
}
|
||||
else if (type == "custom")
|
||||
{
|
||||
m_is_custom = true;
|
||||
absolute.insert(0, m_path.custom());
|
||||
}
|
||||
else
|
||||
{
|
||||
throw_ex<type::RuntimeError>(
|
||||
"must be of type 'repo/<relative>' or 'custom/<relative>'");
|
||||
}
|
||||
m_absolute = std::move(absolute);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
protected:
|
||||
//! \brief Sets pluggable absolute path from given pseudo path
|
||||
//! \param pseudo Pseudo-path ('repo/<relative>' or 'custom/<relative>')
|
||||
//! \param base Operating system absolute paths to pluggable locations
|
||||
//! \exception type::RuntimeError If not a valid pseudo-path
|
||||
PluggablePath(const std::string& pseudo, const type::PluggablePath& path)
|
||||
: m_pseudo(pseudo), m_path(path), m_is_repo(false), m_is_custom(false)
|
||||
{
|
||||
parse();
|
||||
}
|
||||
~PluggablePath() = default;
|
||||
|
||||
PluggablePath(const PluggablePath&) = default;
|
||||
PluggablePath& operator=(const PluggablePath&) = default;
|
||||
|
||||
PluggablePath(PluggablePath&&) = default;
|
||||
PluggablePath& operator=(PluggablePath&&) = default;
|
||||
|
||||
public:
|
||||
//! \brief Mutator to underlying type::PluggablePath
|
||||
//! \warning Use with caution: underlying implementation may change
|
||||
auto& operator()() { return m_path; }
|
||||
|
||||
//! \brief Accessor to underlying type::PluggablePath
|
||||
//! \warning Use with caution: underlying implementation may change
|
||||
const auto& operator()() const { return m_path; }
|
||||
|
||||
public:
|
||||
//! \return The pluggable's pseudo-path
|
||||
const std::string& pseudo() const { return m_pseudo; }
|
||||
|
||||
//! \return The pluggable's operating system absolute path
|
||||
const std::string& absolute() const { return m_absolute; }
|
||||
|
||||
// TODO(unassigned): relative() to current working dir
|
||||
|
||||
//! \return The pluggable's parent directory
|
||||
//! \note This also represents the expected namespace used for pluggable auto-loading
|
||||
const std::string& parent() const { return m_parent; }
|
||||
|
||||
//! \return The pluggable's child (filename)
|
||||
const std::string& child() const { return m_child; }
|
||||
|
||||
//! \return The pluggable's group of parent member and child filename
|
||||
const std::string& family() const { return m_family; }
|
||||
|
||||
//! \return true if pseudo-path describes a repository location
|
||||
bool is_repo() const { return m_is_repo; }
|
||||
|
||||
//! \return true if pseudo-path describes a custom location
|
||||
bool is_custom() const { return m_is_custom; }
|
||||
|
||||
private:
|
||||
type::PluggablePath m_path;
|
||||
std::string m_pseudo, m_absolute;
|
||||
std::string m_parent, m_family, m_child;
|
||||
bool m_is_repo, m_is_custom;
|
||||
};
|
||||
|
||||
//! \brief Base namespace handler for various pluggables (plugins and macros)
|
||||
//!
|
||||
//! \details Handles pluggable namespace, typically used by pluggable
|
||||
//! implementations when auto-(un|re)loading.
|
||||
//!
|
||||
//! \ingroup cpp_plugin_impl cpp_macro_impl
|
||||
//! \since docker-finance 1.1.0
|
||||
class PluggableSpace
|
||||
{
|
||||
protected:
|
||||
explicit PluggableSpace(const type::PluggableSpace& space) : m_space(space) {}
|
||||
~PluggableSpace() = default;
|
||||
|
||||
PluggableSpace(const PluggableSpace&) = default;
|
||||
PluggableSpace& operator=(const PluggableSpace&) = default;
|
||||
|
||||
PluggableSpace(PluggableSpace&&) = default;
|
||||
PluggableSpace& operator=(PluggableSpace&&) = default;
|
||||
|
||||
public:
|
||||
//! \brief Mutator to underlying type::PluggableSpace
|
||||
//! \warning Use with caution: underlying implementation may change
|
||||
auto& operator()() { return m_space; }
|
||||
|
||||
//! \brief Accessor to underlying type::PluggableSpace
|
||||
//! \warning Use with caution: underlying implementation may change
|
||||
const auto& operator()() const { return m_space; }
|
||||
|
||||
public:
|
||||
//! \return The pluggable's outer namespace
|
||||
const std::string& outer() const { return m_space.outer(); }
|
||||
|
||||
//! \return The pluggable's inner namespace
|
||||
const std::string& inner() const { return m_space.inner(); }
|
||||
|
||||
//! \return true if the outer namespace was set
|
||||
bool has_outer() const { return !m_space.outer().empty(); }
|
||||
|
||||
//! \return true if the inner namespace was set
|
||||
bool has_inner() const { return !m_space.inner().empty(); }
|
||||
|
||||
private:
|
||||
type::PluggableSpace m_space;
|
||||
};
|
||||
|
||||
//! \brief Base argument handler for various pluggables (plugins and macros)
|
||||
//!
|
||||
//! \details Handles pluggable arguments, typically used by pluggable
|
||||
//! implementations when auto-(un|re)loading.
|
||||
//!
|
||||
//! \ingroup cpp_plugin_impl cpp_macro_impl
|
||||
//! \since docker-finance 1.1.0
|
||||
class PluggableArgs
|
||||
{
|
||||
protected:
|
||||
explicit PluggableArgs(const type::PluggableArgs& args) : m_args(args) {}
|
||||
~PluggableArgs() = default;
|
||||
|
||||
PluggableArgs(const PluggableArgs&) = default;
|
||||
PluggableArgs& operator=(const PluggableArgs&) = default;
|
||||
|
||||
PluggableArgs(PluggableArgs&&) = default;
|
||||
PluggableArgs& operator=(PluggableArgs&&) = default;
|
||||
|
||||
public:
|
||||
//! \brief Mutator to underlying type::PluggableArgs
|
||||
//! \warning Use with caution: underlying implementation may change
|
||||
auto& operator()() { return m_args; }
|
||||
|
||||
//! \brief Accessor to underlying type::PluggableArgs
|
||||
//! \warning Use with caution: underlying implementation may change
|
||||
const auto& operator()() const { return m_args; }
|
||||
|
||||
public:
|
||||
//! \return The pluggable's loader argument
|
||||
const std::string& load() const { return m_args.load(); }
|
||||
|
||||
//! \return The pluggable's unloader argument
|
||||
const std::string& unload() const { return m_args.unload(); }
|
||||
|
||||
//! \return true if the load argument was set
|
||||
bool has_load() const { return !m_args.load().empty(); }
|
||||
|
||||
//! \return true if the unload argument was set
|
||||
bool has_unload() const { return !m_args.unload().empty(); }
|
||||
|
||||
private:
|
||||
type::PluggableArgs m_args;
|
||||
};
|
||||
|
||||
//! \concept dfi::common::PPath
|
||||
//! \brief Pluggable base implementation constraint (PluggablePath)
|
||||
//! \ref dfi::common::PluggablePath
|
||||
//! \ingroup cpp_plugin_impl cpp_macro_impl
|
||||
//! \since docker-finance 1.1.0
|
||||
template <typename t_path>
|
||||
concept PPath = std::derived_from<t_path, PluggablePath>;
|
||||
|
||||
//! \concept dfi::common::PSpace
|
||||
//! \brief Pluggable base implementation constraint (PluggableSpace)
|
||||
//! \ref dfi::common::PluggableSpace
|
||||
//! \ingroup cpp_plugin_impl cpp_macro_impl
|
||||
//! \since docker-finance 1.1.0
|
||||
template <typename t_space>
|
||||
concept PSpace = std::derived_from<t_space, PluggableSpace>;
|
||||
|
||||
//! \concept dfi::common::PArgs
|
||||
//! \brief Pluggable base implementation constraint (PluggableArgs)
|
||||
//! \ref dfi::common::PluggableArgs
|
||||
//! \ingroup cpp_plugin_impl cpp_macro_impl
|
||||
//! \since docker-finance 1.1.0
|
||||
template <typename t_args>
|
||||
concept PArgs = std::derived_from<t_args, PluggableArgs>;
|
||||
|
||||
//! \brief Base pluggable handler
|
||||
//! \ingroup cpp_plugin_impl cpp_macro_impl
|
||||
//! \since docker-finance 1.1.0
|
||||
template <PPath t_path, PSpace t_space, PArgs t_args>
|
||||
class Pluggable
|
||||
{
|
||||
protected:
|
||||
explicit Pluggable(const type::Pluggable<t_path, t_space, t_args>& plug)
|
||||
: m_plug(plug)
|
||||
{
|
||||
}
|
||||
~Pluggable() = default;
|
||||
|
||||
Pluggable(const Pluggable&) = default;
|
||||
Pluggable& operator=(const Pluggable&) = default;
|
||||
|
||||
Pluggable(Pluggable&&) = default;
|
||||
Pluggable& operator=(Pluggable&&) = default;
|
||||
|
||||
public:
|
||||
//! \brief Mutator to underlying type::Pluggable
|
||||
//! \warning Use with caution: underlying implementation may change
|
||||
auto& operator()() { return m_plug; }
|
||||
|
||||
//! \brief Accessor to underlying type::Pluggable
|
||||
//! \warning Use with caution: underlying implementation may change
|
||||
const auto& operator()() const { return m_plug; }
|
||||
|
||||
public:
|
||||
//! \brief Loads a single pluggable
|
||||
//! \return NPI reference
|
||||
//! \ingroup cpp_plugin_impl cpp_macro_impl
|
||||
//! \since docker-finance 1.1.0
|
||||
const auto& load() const
|
||||
{
|
||||
// Load pluggable file
|
||||
::dfi::common::load(m_plug.path().absolute());
|
||||
|
||||
// Execute pluggable's loader
|
||||
const std::string s{
|
||||
"dfi::" + m_plug.space().outer() + "::" + m_plug.space().inner()};
|
||||
::dfi::common::line(s + "::load(\"" + m_plug.args().load() + "\")");
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \brief Unloads a single pluggable
|
||||
//! \return NPI reference
|
||||
//! \ingroup cpp_plugin_impl cpp_macro_impl
|
||||
//! \since docker-finance 1.1.0
|
||||
const auto& unload() const
|
||||
{
|
||||
// Execute pluggable's unloader
|
||||
const std::string s{
|
||||
"dfi::" + m_plug.space().outer() + "::" + m_plug.space().inner()};
|
||||
::dfi::common::line(s + "::unload(\"" + m_plug.args().unload() + "\")");
|
||||
|
||||
// Unload pluggable file
|
||||
::dfi::common::unload(m_plug.path().absolute());
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \brief Reloads a single pluggable
|
||||
//! \return NPI reference
|
||||
//! \ingroup cpp_plugin_impl cpp_macro_impl
|
||||
//! \since docker-finance 1.1.0
|
||||
const auto& reload() const { return unload().load(); }
|
||||
|
||||
private:
|
||||
type::Pluggable<t_path, t_space, t_args> m_plug;
|
||||
};
|
||||
|
||||
} // namespace common
|
||||
} // namespace dfi
|
||||
|
||||
|
||||
@@ -42,47 +42,110 @@ namespace macro
|
||||
//! \since docker-finance 1.0.0
|
||||
namespace common
|
||||
{
|
||||
//! \brief Load file by path
|
||||
//! \ingroup cpp_macro_impl
|
||||
//! \brief Load macro file by path
|
||||
//! \details
|
||||
//! Example:
|
||||
//! <br>  root [0] dfi::macro::load("test/unit.C")<br>
|
||||
//! <br>  root [0] dfi::macro::load("macro/test/unit.C")<br>
|
||||
//!
|
||||
//! Will load:
|
||||
//! <br>  root/macro/test/unit.C<br>
|
||||
//!
|
||||
//! \note Parent directory is `root/macro`
|
||||
//! \todo Isolate for macros only (similar to plugins)
|
||||
//! \note Parent directory is `root` by default but accepts absolute paths outside of `root`
|
||||
//! \todo Refactor with dfi::common::Pluggable
|
||||
//! \ingroup cpp_macro_impl
|
||||
void load(const std::string& path)
|
||||
{
|
||||
::dfi::common::Command::load(path);
|
||||
::dfi::common::load(path);
|
||||
}
|
||||
|
||||
//! \brief Wrapper to load files by list of paths
|
||||
//! \ingroup cpp_macro_impl
|
||||
//! \brief Load macro files by list of paths
|
||||
//! \details
|
||||
//! Example:
|
||||
//! <br>  root [0] dfi::macro::load({"test/unit.C", "test/benchmark.C"})<br>
|
||||
//! <br>  root [0] dfi::macro::load({"macro/test/unit.C", "macro/test/benchmark.C"})<br>
|
||||
//!
|
||||
//! Will load:
|
||||
//! <br>  root/macro/test/unit.C and root/test/benchmark.C<br>
|
||||
//! <br>  root/macro/test/unit.C and root/macro/test/benchmark.C<br>
|
||||
//!
|
||||
//! \note Parent directory is `root/macro`
|
||||
//! \todo Isolate for macros only (similar to plugins)
|
||||
//! \note Parent directory is `root` by default but accepts absolute paths outside of `root`
|
||||
//! \ingroup cpp_macro_impl
|
||||
//! \todo Refactor with dfi::common::Pluggable
|
||||
void load(const std::initializer_list<std::string>& paths)
|
||||
{
|
||||
for (const auto& path : paths)
|
||||
::dfi::common::Command::load(path);
|
||||
::dfi::common::load(paths);
|
||||
}
|
||||
|
||||
//! \deprecated This will be removed in the v2 API; use `dfi::common` namespace instead
|
||||
//! \brief Unload macro file by path
|
||||
//! \details
|
||||
//! Example:
|
||||
//! <br>  root [0] dfi::macro::unload("macro/test/unit.C")<br>
|
||||
//!
|
||||
//! Will unload:
|
||||
//! <br>  root/macro/test/unit.C<br>
|
||||
//!
|
||||
//! \note Parent directory is `root` by default but accepts absolute paths outside of `root`
|
||||
//! \ingroup cpp_macro_impl
|
||||
//! \todo Refactor with dfi::common::Pluggable
|
||||
void unload(const std::string& path)
|
||||
{
|
||||
::dfi::common::unload(path);
|
||||
}
|
||||
|
||||
//! \brief Unload macro files by list of paths
|
||||
//! \details
|
||||
//! Example:
|
||||
//! <br>  root [0] dfi::macro::unload({"macro/test/unit.C", "macro/test/benchmark.C"})<br>
|
||||
//!
|
||||
//! Will unload:
|
||||
//! <br>  root/macro/test/unit.C and root/macro/test/benchmark.C<br>
|
||||
//!
|
||||
//! \note Parent directory is `root` by default but accepts absolute paths outside of `root`
|
||||
//! \ingroup cpp_macro_impl
|
||||
//! \todo Refactor with dfi::common::Pluggable
|
||||
void unload(const std::initializer_list<std::string>& paths)
|
||||
{
|
||||
::dfi::common::unload(paths);
|
||||
}
|
||||
|
||||
//! \deprecated This will be removed in the v2 API; use the `dfi::common` free functions instead
|
||||
//! \todo Remove in 2.0.0
|
||||
//! \since docker-finance 1.0.0
|
||||
class Command : public ::dfi::common::Command
|
||||
{
|
||||
};
|
||||
|
||||
//! \deprecated This will be removed in the v2 API; use `dfi::common` namespace instead
|
||||
//! \brief Reload macro file by path
|
||||
//! \details
|
||||
//! Example:
|
||||
//! <br>  root [0] dfi::macro::reload("macro/test/unit.C")<br>
|
||||
//!
|
||||
//! Will reload:
|
||||
//! <br>  root/macro/test/unit.C<br>
|
||||
//!
|
||||
//! \note Parent directory is `root` by default but accepts absolute paths outside of `root`
|
||||
//! \ingroup cpp_macro_impl
|
||||
//! \todo Refactor with dfi::common::Pluggable
|
||||
void reload(const std::string& path)
|
||||
{
|
||||
::dfi::common::reload(path);
|
||||
}
|
||||
|
||||
//! \brief Reload macro files by list of paths
|
||||
//! \ingroup cpp_macro_impl
|
||||
//! \details
|
||||
//! Example:
|
||||
//! <br>  root [0] dfi::macro::reload({"macro/test/unit.C", "macro/test/benchmark.C"})<br>
|
||||
//!
|
||||
//! Will reload:
|
||||
//! <br>  root/macro/test/unit.C and root/macro/test/benchmark.C<br>
|
||||
//!
|
||||
//! \note Parent directory is `root` by default but accepts absolute paths outside of `root`
|
||||
//! \todo Refactor with dfi::common::Pluggable
|
||||
void reload(const std::initializer_list<std::string>& paths)
|
||||
{
|
||||
::dfi::common::reload(paths);
|
||||
}
|
||||
|
||||
//! \deprecated This will be removed in the v2 API; use the `dfi::common` free function instead
|
||||
//! \todo Remove in 2.0.0
|
||||
//! \since docker-finance 1.0.0
|
||||
std::string get_env(const std::string& var)
|
||||
@@ -90,7 +153,7 @@ std::string get_env(const std::string& var)
|
||||
return ::dfi::common::get_env(var);
|
||||
}
|
||||
|
||||
//! \deprecated This will be removed in the v2 API; use `dfi::common` namespace instead
|
||||
//! \deprecated This will be removed in the v2 API; use the `dfi::common` free function instead
|
||||
//! \todo Remove in 2.0.0
|
||||
//! \since docker-finance 1.0.0
|
||||
int exec(const std::string& cmd)
|
||||
@@ -98,7 +161,7 @@ int exec(const std::string& cmd)
|
||||
return ::dfi::common::exec(cmd);
|
||||
}
|
||||
|
||||
//! \deprecated This will be removed in the v2 API; use `dfi::common` namespace instead
|
||||
//! \deprecated This will be removed in the v2 API; use the `dfi::common` free function instead
|
||||
//! \todo Remove in 2.0.0
|
||||
//! \since docker-finance 1.0.0
|
||||
std::string make_timestamp()
|
||||
@@ -111,6 +174,7 @@ std::string make_timestamp()
|
||||
//! \ref dfi::macro::common::load(const std::string& path)
|
||||
//! \ingroup cpp_macro
|
||||
//! \since docker-finance 1.1.0
|
||||
//! \todo Refactor with dfi::common::Pluggable
|
||||
void load(const std::string& path)
|
||||
{
|
||||
common::load(path);
|
||||
@@ -119,12 +183,49 @@ void load(const std::string& path)
|
||||
//! \ref dfi::macro::common::load(const std::initializer_list<std::string>& paths)
|
||||
//! \ingroup cpp_macro
|
||||
//! \since docker-finance 1.1.0
|
||||
//! \todo Refactor with dfi::common::Pluggable
|
||||
void load(const std::initializer_list<std::string>& paths)
|
||||
{
|
||||
common::load(paths);
|
||||
}
|
||||
|
||||
// TODO(afiore): unload
|
||||
//! \brief Convenience wrapper to inner common unloader
|
||||
//! \ref dfi::macro::common::unload(const std::string& path)
|
||||
//! \ingroup cpp_macro
|
||||
//! \since docker-finance 1.1.0
|
||||
//! \todo Refactor with dfi::common::Pluggable
|
||||
void unload(const std::string& path)
|
||||
{
|
||||
common::unload(path);
|
||||
}
|
||||
//! \brief Convenience wrapper to inner common unloader
|
||||
//! \ref dfi::macro::common::unload(const std::initializer_list<std::string>& paths)
|
||||
//! \ingroup cpp_macro
|
||||
//! \since docker-finance 1.1.0
|
||||
//! \todo Refactor with dfi::common::Pluggable
|
||||
void unload(const std::initializer_list<std::string>& paths)
|
||||
{
|
||||
common::unload(paths);
|
||||
}
|
||||
|
||||
//! \brief Convenience wrapper to inner common reloader
|
||||
//! \ref dfi::macro::common::reload(const std::string& path)
|
||||
//! \ingroup cpp_macro
|
||||
//! \since docker-finance 1.1.0
|
||||
//! \todo Refactor with dfi::common::Pluggable
|
||||
void reload(const std::string& path)
|
||||
{
|
||||
common::reload(path);
|
||||
}
|
||||
//! \brief Convenience wrapper to inner common reloader
|
||||
//! \ref dfi::macro::common::reload(const std::initializer_list<std::string>& paths)
|
||||
//! \ingroup cpp_macro
|
||||
//! \since docker-finance 1.1.0
|
||||
//! \todo Refactor with dfi::common::Pluggable
|
||||
void reload(const std::initializer_list<std::string>& paths)
|
||||
{
|
||||
common::reload(paths);
|
||||
}
|
||||
|
||||
} // namespace macro
|
||||
} // namespace dfi
|
||||
|
||||
@@ -25,7 +25,9 @@
|
||||
|
||||
#include <initializer_list>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "../../common/type.hh"
|
||||
#include "../../common/utility.hh"
|
||||
|
||||
//! \namespace dfi
|
||||
@@ -35,7 +37,7 @@ namespace dfi
|
||||
//! \namespace dfi::plugin
|
||||
//! \brief docker-finance plugins
|
||||
//! \warning All plugins (repo/custom) must exist within this namespace
|
||||
//! and work within their own inner namespace
|
||||
//! and work within their own inner namespace
|
||||
//! \since docker-finance 1.0.0
|
||||
namespace plugin
|
||||
{
|
||||
@@ -44,94 +46,544 @@ namespace plugin
|
||||
//! \since docker-finance 1.1.0
|
||||
namespace common
|
||||
{
|
||||
//! \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_impl
|
||||
//! \details
|
||||
//! Example:
|
||||
//! <br>  root [0] dfi::plugin::load("repo/example.cc")<br>
|
||||
//!
|
||||
//! Will load:
|
||||
//! <br>  ${DOCKER_FINANCE_CONTAINER_REPO}/plugins/root/example.cc<br>
|
||||
//!
|
||||
//! Example:
|
||||
//! <br>  root [0] dfi::plugin::load("custom/example.cc")<br>
|
||||
//!
|
||||
//! Will load:
|
||||
//! <br>  ${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)
|
||||
//! \brief Plugin's pseudo-path handler
|
||||
//! \note Parent directory for all plugins are outside of repository's `root` directory
|
||||
//! \ingroup cpp_plugin
|
||||
//! \since docker-finance 1.1.0
|
||||
class PluginPath final : public ::dfi::common::PluggablePath
|
||||
{
|
||||
const std::string type{path.substr(0, path.find("/"))};
|
||||
public:
|
||||
//! \param pseudo Must be string "repo/<relative>" or "custom/<relative>"
|
||||
//! where "repo" is a repository plugin, "custom" is a custom plugin,
|
||||
//! and where <relative> is a pseudo-path relative to plugin's
|
||||
//! operating system location.
|
||||
explicit PluginPath(const std::string& pseudo)
|
||||
: ::dfi::common::PluggablePath(
|
||||
pseudo,
|
||||
::dfi::common::type::PluggablePath(
|
||||
{::dfi::common::get_env("DOCKER_FINANCE_CONTAINER_REPO")
|
||||
+ "/plugins/root/",
|
||||
::dfi::common::get_env("DOCKER_FINANCE_CONTAINER_PLUGINS")
|
||||
+ "/root/"}))
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
std::string file{path};
|
||||
file.erase(0, file.find("/") + 1);
|
||||
//! \brief Plugin's namespace handler
|
||||
//! \ingroup cpp_plugin
|
||||
//! \since docker-finance 1.1.0
|
||||
class PluginSpace final : public ::dfi::common::PluggableSpace
|
||||
{
|
||||
public:
|
||||
explicit PluginSpace(const std::string& inner)
|
||||
: ::dfi::common::PluggableSpace(
|
||||
::dfi::common::type::PluggableSpace({"plugin", inner}))
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
if (type == "repo")
|
||||
{
|
||||
file.insert(
|
||||
0,
|
||||
::dfi::common::get_env("DOCKER_FINANCE_CONTAINER_REPO")
|
||||
+ "/plugins/root/");
|
||||
}
|
||||
else if (type == "custom")
|
||||
{
|
||||
file.insert(
|
||||
0,
|
||||
::dfi::common::get_env("DOCKER_FINANCE_CONTAINER_PLUGINS")
|
||||
+ "/root/");
|
||||
}
|
||||
else
|
||||
{
|
||||
::dfi::common::throw_ex<::dfi::common::type::RuntimeError>(
|
||||
"must be of type 'repo/<file>' or 'custom/<file>'");
|
||||
}
|
||||
//! \brief Plugin's arguments handler
|
||||
//! \ingroup cpp_plugin
|
||||
//! \since docker-finance 1.1.0
|
||||
class PluginArgs final : public ::dfi::common::PluggableArgs
|
||||
{
|
||||
public:
|
||||
explicit PluginArgs(const std::string& load, const std::string& unload)
|
||||
: ::dfi::common::PluggableArgs(
|
||||
::dfi::common::type::PluggableArgs({load, unload}))
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
::dfi::common::Command::load(file);
|
||||
//! \brief Plugin handler
|
||||
//! \ingroup cpp_plugin
|
||||
//! \since docker-finance 1.1.0
|
||||
class Plugin final
|
||||
: public ::dfi::common::Pluggable<PluginPath, PluginSpace, PluginArgs>
|
||||
{
|
||||
public:
|
||||
explicit Plugin(
|
||||
::dfi::common::type::Pluggable<PluginPath, PluginSpace, PluginArgs>
|
||||
plugin)
|
||||
: ::dfi::common::Pluggable<PluginPath, PluginSpace, PluginArgs>(plugin)
|
||||
{
|
||||
}
|
||||
};
|
||||
} // namespace common
|
||||
|
||||
//
|
||||
// Loader
|
||||
//
|
||||
|
||||
//! \brief Loads a single plugin
|
||||
//!
|
||||
//! \param path common::PluginPath
|
||||
//! \param args common::PluginArgs
|
||||
//!
|
||||
//! \ref dfi::plugin::common::Plugin
|
||||
//!
|
||||
//! \details
|
||||
//!
|
||||
//! Example 1:
|
||||
//!
|
||||
//!   root [0] dfi::plugin::load({"repo/example/example.cc"}, {"using foo = int; foo f;"})
|
||||
//!
|
||||
//! Will load:
|
||||
//!
|
||||
//!   ${DOCKER_FINANCE_CONTAINER_REPO}/plugins/root/example/example.cc
|
||||
//!
|
||||
//! and pass `using foo = int; foo f;` to the plugin's loader (plugin-implementation defined).
|
||||
//!
|
||||
//!
|
||||
//! Example 2:
|
||||
//!
|
||||
//!   root [0] dfi::plugin::load({"custom/example/example.cc"}, {"using bar = char; bar b;"})
|
||||
//!
|
||||
//! Will load:
|
||||
//!
|
||||
//!   ${DOCKER_FINANCE_CLIENT_PLUGINS}/root/example/example.cc
|
||||
//!
|
||||
//! and pass `using bar = char; bar b;` to the plugin's loader (plugin-implementation defined).
|
||||
//!
|
||||
//! \warning
|
||||
//! To utilize plugin auto-loader functionality, the plugin's parent directory *MUST* align with the plugin's namespace;\n
|
||||
//! e.g., "repo/example/example.cc" requires the plugin's auto-loader to exist in the namespace `dfi::plugin::example`.\n
|
||||
//! To avoid this requisite, though ill-advised, use a `dfi::common` file loader instead.
|
||||
//!
|
||||
//! \ingroup cpp_plugin
|
||||
//! \since docker-finance 1.1.0
|
||||
void load(const common::PluginPath& path, const common::PluginArgs& args)
|
||||
{
|
||||
::dfi::common::type::
|
||||
Pluggable<common::PluginPath, common::PluginSpace, common::PluginArgs>
|
||||
type{path, common::PluginSpace{path.parent()}, args};
|
||||
|
||||
common::Plugin plugin{type};
|
||||
plugin.load();
|
||||
}
|
||||
|
||||
//! \brief Wrapper to load plugins by list of pseudo-paths
|
||||
//! \ingroup cpp_plugin_impl
|
||||
//! \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.
|
||||
//! \brief Convenience wrapper to load a list of single plugins with argument
|
||||
//!
|
||||
//! \ref load(const common::PluginPath& path, const common::PluginArgs& args)
|
||||
//!
|
||||
//! \param plugins List of single plugins
|
||||
//!
|
||||
//! \details
|
||||
//!
|
||||
//! Example:
|
||||
//! <br>  root [0] dfi::plugin::load({"repo/example.cc", "custom/example.cc"})<br>
|
||||
//!
|
||||
//!   root [0] dfi::plugin::load({{"repo/example/example.cc", "using foo = int; foo f;"}, {"custom/example/example.cc", "using bar = char; bar b;"}})
|
||||
//!
|
||||
//! Will load:
|
||||
//! <br>  ${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
|
||||
//!   `${DOCKER_FINANCE_CONTAINER_REPO}/plugins/root/example/example.cc`\n
|
||||
//!   `${DOCKER_FINANCE_CLIENT_PLUGINS}/root/example/example.cc`
|
||||
//!
|
||||
//! And pass plugin-implementation defined auto-loader arguments:
|
||||
//!
|
||||
//!   `using foo = int; foo f;` for `${DOCKER_FINANCE_CONTAINER_REPO}/plugins/root/example/example.cc`\n
|
||||
//!   `using bar = char; bar b;` for `${DOCKER_FINANCE_CLIENT_PLUGINS}/root/example/example.cc`
|
||||
//!
|
||||
//! \warning
|
||||
//! To utilize plugin auto-loader functionality, the plugin's parent directory *MUST* align with the plugin's namespace;\n
|
||||
//! e.g., "repo/example/example.cc" requires the plugin's auto-loader to exist in the namespace `dfi::plugin::example`.\n
|
||||
//! To avoid this requisite, though ill-advised, use a `dfi::common` file loader instead.
|
||||
//!
|
||||
//! \ingroup cpp_plugin
|
||||
//! \since docker-finance 1.1.0
|
||||
void load(
|
||||
const std::initializer_list<
|
||||
std::pair<common::PluginPath, common::PluginArgs>>& plugins)
|
||||
{
|
||||
for (const auto& plugin : plugins)
|
||||
load(plugin.first, plugin.second);
|
||||
}
|
||||
|
||||
//! \brief Convenience wrapper to load a single plugin with optional argument
|
||||
//!
|
||||
//! \ref load(const common::PluginPath& path, const common::PluginArgs& args)
|
||||
//!
|
||||
//! \param path Must be of string "repo/<relative>" or "custom/<relative>" to plugin location, as described by common::PluginPath
|
||||
//!
|
||||
//! \param arg Optional string argument to pass to plugin's auto-loader (plugin-implementation defined)
|
||||
//!
|
||||
//! \details
|
||||
//!
|
||||
//! Example 1:
|
||||
//!
|
||||
//!   root [0] dfi::plugin::load("repo/example.cc", "using foo = int; foo f;")
|
||||
//!
|
||||
//! Will load:
|
||||
//!
|
||||
//!   ${DOCKER_FINANCE_CONTAINER_REPO}/plugins/root/example/example.cc
|
||||
//!
|
||||
//! and pass `using foo = int; foo f;` to the plugin's loader (plugin-implementation defined).
|
||||
//!
|
||||
//!
|
||||
//! Example 2:
|
||||
//!
|
||||
//!   root [0] dfi::plugin::load("custom/example/example.cc", "using bar = char; bar b;")
|
||||
//!
|
||||
//! Will load:
|
||||
//!
|
||||
//!   ${DOCKER_FINANCE_CLIENT_PLUGINS}/root/example/example.cc
|
||||
//!
|
||||
//! and pass `using bar = char; bar b;` to the plugin's loader (plugin-implementation defined).
|
||||
//!
|
||||
//! \warning
|
||||
//! To utilize plugin auto-loader functionality, the plugin's parent directory *MUST* align with the plugin's namespace;\n
|
||||
//! e.g., "repo/example/example.cc" requires the plugin's auto-loader to exist in the namespace `dfi::plugin::example`.\n
|
||||
//! To avoid this requisite, though ill-advised, use a `dfi::common` file loader instead.
|
||||
//!
|
||||
//! \ingroup cpp_plugin
|
||||
//! \since docker-finance 1.1.0
|
||||
void load(const std::string& path, const std::string& arg = {})
|
||||
{
|
||||
load(common::PluginPath{path}, common::PluginArgs{arg, ""});
|
||||
}
|
||||
|
||||
//! \brief Convenience wrapper to load a list of plugins with no arguments
|
||||
//!
|
||||
//! \ref load(const std::string& path, const std::string& arg)
|
||||
//!
|
||||
//! \param path Must be of string "repo/<relative>" or "custom/<relative>" to plugin location, as described by common::PluginPath
|
||||
//!
|
||||
//! \details
|
||||
//!
|
||||
//! Example 1:
|
||||
//!
|
||||
//!   root [0] dfi::plugin::load({"repo/example/example.cc", "custom/example/example.cc"})
|
||||
//!
|
||||
//! Will load both:
|
||||
//!
|
||||
//!   ${DOCKER_FINANCE_CONTAINER_REPO}/plugins/root/example/example.cc\n
|
||||
//!   ${DOCKER_FINANCE_CLIENT_PLUGINS}/root/example/example.cc
|
||||
//!
|
||||
//! \warning
|
||||
//! To utilize plugin auto-loader functionality, the plugin's parent directory *MUST* align with the plugin's namespace;\n
|
||||
//! e.g., "repo/example/example.cc" requires the plugin's auto-loader to exist in the namespace `dfi::plugin::example`.\n
|
||||
//! To avoid this requisite, though ill-advised, use a `dfi::common` file loader instead.
|
||||
//!
|
||||
//! \ingroup cpp_plugin
|
||||
//! \since docker-finance 1.0.0
|
||||
void load(const std::initializer_list<std::string>& paths)
|
||||
{
|
||||
for (const auto& path : paths)
|
||||
::dfi::plugin::common::load(path);
|
||||
load(path);
|
||||
}
|
||||
} // namespace common
|
||||
|
||||
//! \brief Convenience wrapper to inner common loader
|
||||
//
|
||||
// Unloader
|
||||
//
|
||||
|
||||
//! \brief Unloads a single plugin
|
||||
//!
|
||||
//! \param path common::PluginPath
|
||||
//! \param args common::PluginArgs
|
||||
//!
|
||||
//! \ref dfi::plugin::common::Plugin
|
||||
//!
|
||||
//! \details
|
||||
//!
|
||||
//! Example 1:
|
||||
//!
|
||||
//!   root [0] dfi::plugin::unload({"repo/example/example.cc"}, {"using foo = int; foo f;"})
|
||||
//!
|
||||
//! Will unload:
|
||||
//!
|
||||
//!   ${DOCKER_FINANCE_CONTAINER_REPO}/plugins/root/example/example.cc
|
||||
//!
|
||||
//! and pass `using foo = int; foo f;` to the plugin's unloader (plugin-implementation defined).
|
||||
//!
|
||||
//!
|
||||
//! Example 2:
|
||||
//!
|
||||
//!   root [0] dfi::plugin::unload({"custom/example/example.cc"}, {"using bar = char; bar b;"})
|
||||
//!
|
||||
//! Will unload:
|
||||
//!
|
||||
//!   ${DOCKER_FINANCE_CLIENT_PLUGINS}/root/example/example.cc
|
||||
//!
|
||||
//! and pass `using bar = char; bar b;` to the plugin's unloader (plugin-implementation defined).
|
||||
//!
|
||||
//! \warning
|
||||
//! To utilize plugin auto-unloader functionality, the plugin's parent directory *MUST* align with the plugin's namespace;\n
|
||||
//! e.g., "repo/example/example.cc" requires the plugin's auto-unloader to exist in the namespace `dfi::plugin::example`.\n
|
||||
//! To avoid this requisite, though ill-advised, use a `dfi::common` file loader instead.
|
||||
//!
|
||||
//! \ingroup cpp_plugin
|
||||
//! \since docker-finance 1.1.0
|
||||
void load(const std::string& path)
|
||||
void unload(const common::PluginPath& path, const common::PluginArgs& args)
|
||||
{
|
||||
common::load(path);
|
||||
::dfi::common::type::
|
||||
Pluggable<common::PluginPath, common::PluginSpace, common::PluginArgs>
|
||||
type{path, common::PluginSpace{path.parent()}, args};
|
||||
|
||||
common::Plugin plugin{type};
|
||||
plugin.unload();
|
||||
}
|
||||
//! \brief Convenience wrapper to inner common loader
|
||||
|
||||
//! \brief Convenience wrapper to unload a list of single plugins with arguments
|
||||
//!
|
||||
//! \ref unload(const common::PluginPath& path, const common::PluginArgs& args)
|
||||
//!
|
||||
//! \param plugins List of single plugins
|
||||
//!
|
||||
//! \details
|
||||
//!
|
||||
//! Example:
|
||||
//!
|
||||
//!   root [0] dfi::plugin::unload({{"repo/example/example.cc", "using foo = int; foo f;"}, {"custom/example/example.cc", "using bar = char; bar b;"}})
|
||||
//!
|
||||
//! Will unload:
|
||||
//!
|
||||
//!   `${DOCKER_FINANCE_CONTAINER_REPO}/plugins/root/example/example.cc`\n
|
||||
//!   `${DOCKER_FINANCE_CLIENT_PLUGINS}/root/example/example.cc`
|
||||
//!
|
||||
//! And pass plugin-implementation defined auto-unloader arguments:
|
||||
//!
|
||||
//!   `using foo = int; foo f;` for `${DOCKER_FINANCE_CONTAINER_REPO}/plugins/root/example/example.cc`\n
|
||||
//!   `using bar = char; bar b;` for `${DOCKER_FINANCE_CLIENT_PLUGINS}/root/example/example.cc`
|
||||
//!
|
||||
//! \warning
|
||||
//! To utilize plugin auto-unloader functionality, the plugin's parent directory *MUST* align with the plugin's namespace;\n
|
||||
//! e.g., "repo/example/example.cc" requires the plugin's auto-unloader to exist in the namespace `dfi::plugin::example`.\n
|
||||
//! To avoid this requisite, though ill-advised, use a `dfi::common` file loader instead.
|
||||
//!
|
||||
//! \ingroup cpp_plugin
|
||||
//! \since docker-finance 1.1.0
|
||||
void load(const std::initializer_list<std::string>& paths)
|
||||
void unload(
|
||||
const std::initializer_list<
|
||||
std::pair<common::PluginPath, common::PluginArgs>>& plugins)
|
||||
{
|
||||
common::load(paths);
|
||||
for (const auto& plugin : plugins)
|
||||
unload(plugin.first, plugin.second);
|
||||
}
|
||||
|
||||
// TODO(afiore): unload
|
||||
//! \brief Convenience wrapper to unload a single plugin with optional argument
|
||||
//!
|
||||
//! \ref unload(const common::PluginPath& path, const common::PluginArgs& args)
|
||||
//!
|
||||
//! \param path Must be of string "repo/<relative>" or "custom/<relative>" to plugin location, as described by common::PluginPath
|
||||
//!
|
||||
//! \param arg Optional string argument to pass to plugin's auto-unloader (plugin-implementation defined)
|
||||
//!
|
||||
//! \details
|
||||
//!
|
||||
//! Example 1:
|
||||
//!
|
||||
//!   root [0] dfi::plugin::unload("repo/example/example.cc", "using foo = int; foo f;")
|
||||
//!
|
||||
//! Will unload:
|
||||
//!
|
||||
//!   ${DOCKER_FINANCE_CONTAINER_REPO}/plugins/root/example/example.cc
|
||||
//!
|
||||
//! and pass `using foo = int; foo f;` to the plugin's unloader (plugin-implementation defined).
|
||||
//!
|
||||
//!
|
||||
//! Example 2:
|
||||
//!
|
||||
//!   root [0] dfi::plugin::unload("custom/example/example.cc", "using bar = char; bar b;")
|
||||
//!
|
||||
//! Will unload:
|
||||
//!
|
||||
//!   ${DOCKER_FINANCE_CLIENT_PLUGINS}/root/example/example.cc
|
||||
//!
|
||||
//! and pass `using bar = char; bar b;` to the plugin's unloader (plugin-implementation defined).
|
||||
//!
|
||||
//! \warning
|
||||
//! To utilize plugin auto-unloader functionality, the plugin's parent directory *MUST* align with the plugin's namespace;\n
|
||||
//! e.g., "repo/example/example.cc" requires the plugin's auto-unloader to exist in the namespace `dfi::plugin::example`.\n
|
||||
//! To avoid this requisite, though ill-advised, use a `dfi::common` file loader instead.
|
||||
//!
|
||||
//! \ingroup cpp_plugin
|
||||
//! \since docker-finance 1.1.0
|
||||
void unload(const std::string& path, const std::string& arg = {})
|
||||
{
|
||||
unload(common::PluginPath{path}, common::PluginArgs{"", arg});
|
||||
}
|
||||
|
||||
//! \brief Convenience wrapper to unload a list of plugins with no arguments
|
||||
//!
|
||||
//! \ref unload(const std::string& path, const std::string& arg)
|
||||
//!
|
||||
//! \param path Must be of string "repo/<relative>" or "custom/<relative>" to plugin location, as described by common::PluginPath
|
||||
//!
|
||||
//! \details
|
||||
//!
|
||||
//! Example 1:
|
||||
//!
|
||||
//!   root [0] dfi::plugin::unload({"repo/example/example.cc", "custom/example/example.cc"})
|
||||
//!
|
||||
//! Will unload both:
|
||||
//!
|
||||
//!   ${DOCKER_FINANCE_CONTAINER_REPO}/plugins/root/example/example.cc\n
|
||||
//!   ${DOCKER_FINANCE_CLIENT_PLUGINS}/root/example/example.cc
|
||||
//!
|
||||
//! \warning
|
||||
//! To utilize plugin auto-unloader functionality, the plugin's parent directory *MUST* align with the plugin's namespace;\n
|
||||
//! e.g., "repo/example/example.cc" requires the plugin's auto-unloader to exist in the namespace `dfi::plugin::example`.\n
|
||||
//! To avoid this requisite, though ill-advised, use a `dfi::common` file loader instead.
|
||||
//!
|
||||
//! \ingroup cpp_plugin
|
||||
//! \since docker-finance 1.1.0
|
||||
void unload(const std::initializer_list<std::string>& paths)
|
||||
{
|
||||
for (const auto& path : paths)
|
||||
unload(path);
|
||||
}
|
||||
|
||||
//
|
||||
// Reloader
|
||||
//
|
||||
|
||||
//! \brief Reloads a single plugin
|
||||
//!
|
||||
//! \param path common::PluginPath
|
||||
//! \param args common::PluginArgs
|
||||
//!
|
||||
//! \ref dfi::plugin::common::Plugin
|
||||
//!
|
||||
//! \details
|
||||
//!
|
||||
//! Example 1:
|
||||
//!
|
||||
//!   root [0] dfi::plugin::reload({"repo/example/example.cc"}, {"using foo = int; foo f;", "using bar = char; bar b;"})
|
||||
//!
|
||||
//! Will reload:
|
||||
//!
|
||||
//!   ${DOCKER_FINANCE_CONTAINER_REPO}/plugins/root/example/example.cc
|
||||
//!
|
||||
//! and pass `using bar = char; bar b;` to the plugin's unloader (plugin-implementation defined)
|
||||
//! and pass `using foo = int; foo f;` to the plugin's loader (plugin-implementation defined)
|
||||
//!
|
||||
//! \warning
|
||||
//! To utilize plugin auto-(un)loader functionality, the plugin's parent directory *MUST* align with the plugin's namespace;\n
|
||||
//! e.g., "repo/example/example.cc" requires the plugin's auto-(un)loader to exist in the namespace `dfi::plugin::example`.\n
|
||||
//! To avoid this requisite, though ill-advised, use a `dfi::common` file loader instead.
|
||||
//!
|
||||
//! \ingroup cpp_plugin
|
||||
//! \since docker-finance 1.1.0
|
||||
void reload(const common::PluginPath& path, const common::PluginArgs& args)
|
||||
{
|
||||
::dfi::common::type::
|
||||
Pluggable<common::PluginPath, common::PluginSpace, common::PluginArgs>
|
||||
type{path, common::PluginSpace{path.parent()}, args};
|
||||
|
||||
common::Plugin plugin{type};
|
||||
plugin.reload();
|
||||
}
|
||||
|
||||
//! \brief Convenience wrapper to unload a list of single plugins with arguments
|
||||
//!
|
||||
//! \ref reload(const common::PluginPath& path, const common::PluginArgs& args)
|
||||
//!
|
||||
//! \param plugins List of populated pair of common::PluginPath and common::PluginArgs
|
||||
//!
|
||||
//! \details
|
||||
//!
|
||||
//! Example:
|
||||
//!   root [0] dfi::plugin::reload({{"repo/example/example.cc", "using foo = int; foo f;"}, {"custom/example/example.cc", "using bar = char; bar b;"}})
|
||||
//!
|
||||
//! Will reload:
|
||||
//!
|
||||
//!   `${DOCKER_FINANCE_CONTAINER_REPO}/plugins/root/example/example.cc`\n
|
||||
//!   `${DOCKER_FINANCE_CLIENT_PLUGINS}/root/example/example.cc`
|
||||
//!
|
||||
//! And pass plugin-implementation defined auto-loader arguments:
|
||||
//!
|
||||
//!   `using foo = int; foo f;` for `${DOCKER_FINANCE_CONTAINER_REPO}/plugins/root/example/example.cc`\n
|
||||
//!   `using bar = char; bar b;` for `${DOCKER_FINANCE_CLIENT_PLUGINS}/root/example/example.cc`
|
||||
//!
|
||||
//! \warning
|
||||
//! To utilize plugin auto-(un)loader functionality, the plugin's parent directory *MUST* align with the plugin's namespace;\n
|
||||
//! e.g., "repo/example/example.cc" requires the plugin's auto-(un)loader to exist in the namespace `dfi::plugin::example`.\n
|
||||
//! To avoid this requisite, though ill-advised, use a `dfi::common` file loader instead.
|
||||
//!
|
||||
//! \ingroup cpp_plugin
|
||||
//! \since docker-finance 1.1.0
|
||||
void reload(
|
||||
const std::initializer_list<
|
||||
std::pair<common::PluginPath, common::PluginArgs>>& plugins)
|
||||
{
|
||||
for (const auto& plugin : plugins)
|
||||
reload(plugin.first, plugin.second);
|
||||
}
|
||||
|
||||
//! \brief Convenience wrapper to reload a single plugin with optional arguments
|
||||
//!
|
||||
//! \ref reload(const common::PluginPath& path, const common::PluginArgs& args)
|
||||
//!
|
||||
//! \param path Must be of string "repo/<relative>" or "custom/<relative>" to plugin location, as described by common::PluginPath
|
||||
//!
|
||||
//! \param args Optional pair of arguments to pass to plugin's auto-loader/unloader (plugin-implementation defined)
|
||||
//!
|
||||
//! \details
|
||||
//!
|
||||
//! Example 1:
|
||||
//!
|
||||
//!   root [0] dfi::plugin::reload("repo/example/example.cc", {"using foo = int; foo f;", ""})
|
||||
//!
|
||||
//! Will reload:
|
||||
//!
|
||||
//!   ${DOCKER_FINANCE_CONTAINER_REPO}/plugins/root/example/example.cc
|
||||
//!
|
||||
//! and pass `using foo = int; foo f;` to the plugin's auto-loader (plugin-implementation defined).
|
||||
//!
|
||||
//!
|
||||
//! Example 2:
|
||||
//!
|
||||
//!   root [0] dfi::plugin::reload("custom/example/example.cc", {"", "using bar = char; bar b;"})
|
||||
//!
|
||||
//! Will reload:
|
||||
//!
|
||||
//!   ${DOCKER_FINANCE_CLIENT_PLUGINS}/root/example/example.cc
|
||||
//!
|
||||
//! and pass `using bar = char; bar b;` to the plugin's auto-unloader (plugin-implementation defined).
|
||||
//!
|
||||
//! \warning
|
||||
//! To utilize plugin auto-(un)loader functionality, the plugin's parent directory *MUST* align with the plugin's namespace;\n
|
||||
//! e.g., "repo/example/example.cc" requires the plugin's auto-(un)loader to exist in the namespace `dfi::plugin::example`.\n
|
||||
//! To avoid this requisite, though ill-advised, use a `dfi::common` file loader instead.
|
||||
//!
|
||||
//! \ingroup cpp_plugin
|
||||
//! \since docker-finance 1.1.0
|
||||
void reload(
|
||||
const std::string& path,
|
||||
const std::pair<std::string, std::string>& args = {})
|
||||
{
|
||||
reload(common::PluginPath{path}, common::PluginArgs{args.first, args.second});
|
||||
}
|
||||
|
||||
//! \brief Convenience wrapper to reload a list of plugins with no arguments
|
||||
//!
|
||||
//! \ref reload(const std::string& path, const std::string& arg)
|
||||
//!
|
||||
//! \param path Must be of string "repo/<relative>" or "custom/<relative>" to plugin location, as described by common::PluginPath
|
||||
//!
|
||||
//! \details
|
||||
//!
|
||||
//! Example 1:
|
||||
//!
|
||||
//!   root [0] dfi::plugin::reload({"repo/example/example.cc", "custom/example/example.cc"})
|
||||
//!
|
||||
//! Will reload both:
|
||||
//!
|
||||
//!   ${DOCKER_FINANCE_CONTAINER_REPO}/plugins/root/example/example.cc\n
|
||||
//!   ${DOCKER_FINANCE_CLIENT_PLUGINS}/root/example/example.cc
|
||||
//!
|
||||
//! \warning
|
||||
//! To utilize plugin auto-(un)loader functionality, the plugin's parent directory *MUST* align with the plugin's namespace;\n
|
||||
//! e.g., "repo/example/example.cc" requires the plugin's auto-(un)loader to exist in the namespace `dfi::plugin::example`.\n
|
||||
//! To avoid this requisite, though ill-advised, use a `dfi::common` file loader instead.
|
||||
//!
|
||||
//! \ingroup cpp_plugin
|
||||
//! \since docker-finance 1.1.0
|
||||
void reload(const std::initializer_list<std::string>& paths)
|
||||
{
|
||||
for (const auto& path : paths)
|
||||
reload(path);
|
||||
}
|
||||
} // namespace plugin
|
||||
} // namespace dfi
|
||||
|
||||
|
||||
Reference in New Issue
Block a user