changeset 731:9d13aabfd63a

Irccd: plugin now have internal id
author David Demelier <markand@malikania.fr>
date Thu, 19 Jul 2018 07:22:36 +0200
parents 2496ebc42b07
children e53b013c8938
files libirccd-js/irccd/js/js_plugin.cpp libirccd-js/irccd/js/js_plugin.hpp libirccd-js/irccd/js/logger_jsapi.cpp libirccd-js/irccd/js/plugin_jsapi.cpp libirccd-test/irccd/test/js_test.hpp libirccd-test/irccd/test/plugin_test.cpp libirccd/irccd/daemon/command/plugin_list_command.cpp libirccd/irccd/daemon/command/plugin_load_command.cpp libirccd/irccd/daemon/dynlib_plugin.cpp libirccd/irccd/daemon/plugin.cpp libirccd/irccd/daemon/plugin.hpp libirccd/irccd/daemon/service/plugin_service.cpp libirccd/irccd/daemon/service/plugin_service.hpp libirccd/irccd/daemon/service/server_service.cpp plugins/links/links.cpp tests/src/irccdctl/cli-plugin-config/main.cpp tests/src/irccdctl/cli-plugin-info/main.cpp tests/src/irccdctl/cli-plugin-list/main.cpp tests/src/irccdctl/cli-plugin-load/main.cpp tests/src/irccdctl/cli-plugin-reload/main.cpp tests/src/irccdctl/cli-plugin-unload/main.cpp tests/src/libirccd-js/js-plugin/main.cpp tests/src/libirccd/command-plugin-config/main.cpp tests/src/libirccd/command-plugin-info/main.cpp tests/src/libirccd/command-plugin-list/main.cpp tests/src/libirccd/command-plugin-load/main.cpp tests/src/libirccd/command-plugin-reload/main.cpp tests/src/libirccd/command-plugin-unload/main.cpp tests/src/libirccd/dynlib-plugin/test_plugin.cpp tests/src/plugins/plugin/main.cpp
diffstat 30 files changed, 381 insertions(+), 250 deletions(-) [+]
line wrap: on
line diff
--- a/libirccd-js/irccd/js/js_plugin.cpp	Wed Jul 18 13:49:56 2018 +0200
+++ b/libirccd-js/irccd/js/js_plugin.cpp	Thu Jul 19 07:22:36 2018 +0200
@@ -128,8 +128,9 @@
     duk_pop(context_);
 }
 
-js_plugin::js_plugin(std::string_view path)
-    : path_(path)
+js_plugin::js_plugin(std::string id, std::string path)
+    : plugin(std::move(id))
+    , path_(path)
 {
     dukx_stack_assert sa(context_);
 
@@ -360,12 +361,12 @@
     return modules_;
 }
 
-auto js_plugin_loader::open(std::string_view, std::string_view path) -> std::shared_ptr<plugin>
+auto js_plugin_loader::open(std::string_view id, std::string_view path) -> std::shared_ptr<plugin>
 {
     if (path.rfind(".js") == std::string::npos)
         return nullptr;
 
-    auto plugin = std::make_shared<js_plugin>(path);
+    auto plugin = std::make_shared<js_plugin>(std::string(id), std::string(path));
 
     for (const auto& mod : modules_)
         mod->load(irccd_, plugin);
--- a/libirccd-js/irccd/js/js_plugin.hpp	Wed Jul 18 13:49:56 2018 +0200
+++ b/libirccd-js/irccd/js/js_plugin.hpp	Thu Jul 19 07:22:36 2018 +0200
@@ -76,9 +76,10 @@
     /**
      * Constructor.
      *
+     * \param id the plugin id
      * \param path the path to the plugin
      */
-    js_plugin(std::string_view path);
+    js_plugin(std::string id, std::string path);
 
     /**
      * Access the Duktape context.
--- a/libirccd-js/irccd/js/logger_jsapi.cpp	Wed Jul 18 13:49:56 2018 +0200
+++ b/libirccd-js/irccd/js/logger_jsapi.cpp	Thu Jul 19 07:22:36 2018 +0200
@@ -33,7 +33,7 @@
 
 duk_ret_t print(duk_context* ctx, unsigned level)
 {
-    assert(level >= 0 && level <= 2);
+    assert(level <= 2);
 
     try {
         auto& sink = dukx_type_traits<irccd>::self(ctx).get_log();
@@ -41,13 +41,13 @@
 
         switch (level) {
         case 0:
-            sink.debug(static_cast<const plugin&>(*self)) << duk_require_string(ctx, 0) << std::endl;
+            sink.debug<plugin>(*self) << duk_require_string(ctx, 0) << std::endl;
             break;
         case 1:
-            sink.info(static_cast<const plugin&>(*self)) << duk_require_string(ctx, 0) << std::endl;
+            sink.info<plugin>(*self) << duk_require_string(ctx, 0) << std::endl;
             break;
         default:
-            sink.warning(static_cast<const plugin&>(*self)) << duk_require_string(ctx, 0) << std::endl;
+            sink.warning<plugin>(*self) << duk_require_string(ctx, 0) << std::endl;
             break;
         }
     } catch (const std::exception& ex) {
--- a/libirccd-js/irccd/js/plugin_jsapi.cpp	Wed Jul 18 13:49:56 2018 +0200
+++ b/libirccd-js/irccd/js/plugin_jsapi.cpp	Thu Jul 19 07:22:36 2018 +0200
@@ -252,8 +252,8 @@
 
     duk_push_array(ctx);
 
-    for (const auto& [k, _] : dukx_type_traits<irccd>::self(ctx).plugins().all()) {
-        dukx_push(ctx, k);
+    for (const auto& plg : dukx_type_traits<irccd>::self(ctx).plugins().all()) {
+        dukx_push(ctx, plg->get_id());
         duk_put_prop_index(ctx, -2, i++);
     }
 
@@ -280,7 +280,8 @@
 duk_idx_t Plugin_load(duk_context* ctx)
 {
     return wrap(ctx, [&] {
-        dukx_type_traits<irccd>::self(ctx).plugins().load(dukx_require<std::string>(ctx, 0));
+        dukx_type_traits<irccd>::self(ctx).plugins().load(
+            dukx_require<std::string_view>(ctx, 0), "");
 
         return 0;
     });
--- a/libirccd-test/irccd/test/js_test.hpp	Wed Jul 18 13:49:56 2018 +0200
+++ b/libirccd-test/irccd/test/js_test.hpp	Thu Jul 19 07:22:36 2018 +0200
@@ -79,7 +79,7 @@
 
 template <typename... Modules>
 js_test<Modules...>::js_test(const std::string& plugin_path)
-    : plugin_(new js_plugin(plugin_path))
+    : plugin_(new js_plugin("test", plugin_path))
     , server_(new journal_server(service_, "test"))
 {
     irccd_.set_log(std::make_unique<logger::silent_sink>());
--- a/libirccd-test/irccd/test/plugin_test.cpp	Wed Jul 18 13:49:56 2018 +0200
+++ b/libirccd-test/irccd/test/plugin_test.cpp	Thu Jul 19 07:22:36 2018 +0200
@@ -44,11 +44,11 @@
     : server_(std::make_shared<journal_server>(service_, "test", "local"))
 {
     server_->set_nickname("irccd");
-    plugin_ = std::make_unique<js_plugin>(std::move(path));
+    plugin_ = std::make_unique<js_plugin>("test", std::move(path));
 
     irccd_.set_log(std::make_unique<logger::silent_sink>());
     irccd_.get_log().set_verbose(false);
-    irccd_.plugins().add("test", plugin_);
+    irccd_.plugins().add(plugin_);
     irccd_.servers().add(server_);
 
     irccd_jsapi().load(irccd_, plugin_);
--- a/libirccd/irccd/daemon/command/plugin_list_command.cpp	Wed Jul 18 13:49:56 2018 +0200
+++ b/libirccd/irccd/daemon/command/plugin_list_command.cpp	Thu Jul 19 07:22:36 2018 +0200
@@ -16,8 +16,6 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <algorithm>
-
 #include <irccd/daemon/irccd.hpp>
 #include <irccd/daemon/transport_client.hpp>
 
@@ -36,10 +34,8 @@
 {
     auto list = nlohmann::json::array();
 
-    for (const auto& [key, _] : irccd.plugins().all())
-        list += key;
-
-    std::sort(list.begin(), list.end());
+    for (const auto& plg : irccd.plugins().all())
+        list += plg->get_id();
 
     client.write({
         { "command",    "plugin-list"   },
--- a/libirccd/irccd/daemon/command/plugin_load_command.cpp	Wed Jul 18 13:49:56 2018 +0200
+++ b/libirccd/irccd/daemon/command/plugin_load_command.cpp	Thu Jul 19 07:22:36 2018 +0200
@@ -40,7 +40,7 @@
     if (!id || !string_util::is_identifier(*id))
         throw plugin_error(plugin_error::invalid_identifier);
 
-    irccd.plugins().load(*id);
+    irccd.plugins().load(*id, "");
     client.success("plugin-load");
 }
 
--- a/libirccd/irccd/daemon/dynlib_plugin.cpp	Wed Jul 18 13:49:56 2018 +0200
+++ b/libirccd/irccd/daemon/dynlib_plugin.cpp	Thu Jul 19 07:22:36 2018 +0200
@@ -75,7 +75,7 @@
     const auto [ abisym, initsym ] = symbol(pathstr);
 
     using abisym_func_type = version ();
-    using initsym_func_type = std::unique_ptr<plugin> ();
+    using initsym_func_type = std::unique_ptr<plugin> (std::string);
 
     const auto abi = boost::dll::import_alias<abisym_func_type>(pathstr, abisym);
     const auto init = boost::dll::import_alias<initsym_func_type>(pathstr, initsym);
@@ -86,7 +86,7 @@
     if (current.major != abi().major || current.abi != abi().abi)
         throw plugin_error(plugin_error::exec_error, idstr, "incompatible version");
 
-    auto plg = init();
+    auto plg = init(idstr);
 
     if (!plg)
         throw plugin_error(plugin_error::exec_error, idstr, "invalid plugin");
--- a/libirccd/irccd/daemon/plugin.cpp	Wed Jul 18 13:49:56 2018 +0200
+++ b/libirccd/irccd/daemon/plugin.cpp	Thu Jul 19 07:22:36 2018 +0200
@@ -16,16 +16,148 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#include <cassert>
 #include <sstream>
 
 #include <boost/filesystem.hpp>
 
 #include <irccd/system.hpp>
+#include <irccd/string_util.hpp>
 
 #include "plugin.hpp"
 
 namespace irccd {
 
+plugin::plugin(std::string id) noexcept
+    : id_(std::move(id))
+{
+    assert(string_util::is_identifier(id_));
+}
+
+auto plugin::get_id() const noexcept -> const std::string&
+{
+    return id_;
+}
+
+auto plugin::get_author() const noexcept -> std::string_view
+{
+    return "unknown";
+}
+
+auto plugin::get_license() const noexcept -> std::string_view
+{
+    return "unknown";
+}
+
+auto plugin::get_summary() const noexcept -> std::string_view
+{
+    return "unknown";
+}
+
+auto plugin::get_version() const noexcept -> std::string_view
+{
+    return "unknown";
+}
+
+auto plugin::get_options() const -> map
+{
+    return {};
+}
+
+void plugin::set_options(const map&)
+{
+}
+
+auto plugin::get_formats() const -> map
+{
+    return {};
+}
+
+void plugin::set_formats(const map&)
+{
+}
+
+auto plugin::get_paths() const -> map
+{
+    return {};
+}
+
+void plugin::set_paths(const map&)
+{
+}
+
+void plugin::handle_command(irccd&, const message_event&)
+{
+}
+
+void plugin::handle_connect(irccd&, const connect_event&)
+{
+}
+
+void plugin::handle_disconnect(irccd&, const disconnect_event&)
+{
+}
+
+void plugin::handle_invite(irccd&, const invite_event&)
+{
+}
+
+void plugin::handle_join(irccd&, const join_event&)
+{
+}
+
+void plugin::handle_kick(irccd&, const kick_event&)
+{
+}
+
+void plugin::handle_load(irccd&)
+{
+}
+
+void plugin::handle_message(irccd&, const message_event&)
+{
+}
+
+void plugin::handle_me(irccd&, const me_event&)
+{
+}
+
+void plugin::handle_mode(irccd&, const mode_event&)
+{
+}
+
+void plugin::handle_names(irccd&, const names_event&)
+{
+}
+
+void plugin::handle_nick(irccd&, const nick_event&)
+{
+}
+
+void plugin::handle_notice(irccd&, const notice_event&)
+{
+}
+
+void plugin::handle_part(irccd&, const part_event&)
+{
+}
+
+void plugin::handle_reload(irccd&)
+{
+}
+
+void plugin::handle_topic(irccd&, const topic_event&)
+{
+}
+
+void plugin::handle_unload(irccd&)
+{
+}
+
+void plugin::handle_whois(irccd&, const whois_event&)
+{
+}
+
 plugin_loader::plugin_loader(std::vector<std::string> directories,
               std::vector<std::string> extensions) noexcept
     : directories_(std::move(directories))
--- a/libirccd/irccd/daemon/plugin.hpp	Wed Jul 18 13:49:56 2018 +0200
+++ b/libirccd/irccd/daemon/plugin.hpp	Thu Jul 19 07:22:36 2018 +0200
@@ -72,12 +72,31 @@
      */
     using map = std::unordered_map<std::string, std::string>;
 
+private:
+    std::string id_;
+
+public:
+    /**
+     * Construct a plugin.
+     *
+     * \pre id must be a valid identifier
+     * \param id the plugin id
+     */
+    plugin(std::string id) noexcept;
+
     /**
      * Temporary, close all timers.
      */
     virtual ~plugin() = default;
 
     /**
+     * Get user unique id.
+     *
+     * \return the plugin id
+     */
+    auto get_id() const noexcept -> const std::string&;
+
+    /**
      * Get the plugin name.
      *
      * \return the plugin name
@@ -89,100 +108,70 @@
      *
      * \return the author
      */
-    virtual auto get_author() const noexcept -> std::string_view
-    {
-        return "unknown";
-    }
+    virtual auto get_author() const noexcept -> std::string_view;
 
     /**
      * Get the license.
      *
      * \return the license
      */
-    virtual auto get_license() const noexcept -> std::string_view
-    {
-        return "unknown";
-    }
+    virtual auto get_license() const noexcept -> std::string_view;
 
     /**
      * Get the summary.
      *
      * \return the summary
      */
-    virtual auto get_summary() const noexcept -> std::string_view
-    {
-        return "unknown";
-    }
+    virtual auto get_summary() const noexcept -> std::string_view;
 
     /**
      * Get the version.
      *
      * \return the version
      */
-    virtual auto get_version() const noexcept -> std::string_view
-    {
-        return "unknown";
-    }
+    virtual auto get_version() const noexcept -> std::string_view;
 
     /**
      * Get all options.
      *
      * \return options
      */
-    virtual auto get_options() const -> map
-    {
-        return {};
-    }
+    virtual auto get_options() const -> map;
 
     /**
      * Set all options.
      *
      * \param map the options
      */
-    virtual void set_options(const map& map)
-    {
-        (void)map;
-    }
+    virtual void set_options(const map& map);
 
     /**
      * Get all formats.
      *
      * \return formats
      */
-    virtual auto get_formats() const -> map
-    {
-        return {};
-    }
+    virtual auto get_formats() const -> map;
 
     /**
      * Set all formats.
      *
      * \param map the formats
      */
-    virtual void set_formats(const map& map)
-    {
-        (void)map;
-    }
+    virtual void set_formats(const map& map);
 
     /**
      * Get all paths.
      *
      * \return paths
      */
-    virtual auto get_paths() const -> map
-    {
-        return {};
-    }
+    virtual auto get_paths() const -> map;
 
     /**
      * Set all paths.
      *
      * \param map the paths
      */
-    virtual void set_paths(const map& map)
-    {
-        (void)map;
-    }
+    virtual void set_paths(const map& map);
 
     /**
      * On channel message. This event will call onMessage or
@@ -192,11 +181,7 @@
      * \param irccd the irccd instance
      * \param event the event
      */
-    virtual void handle_command(irccd& irccd, const message_event& event)
-    {
-        (void)irccd;
-        (void)event;
-    }
+    virtual void handle_command(irccd& irccd, const message_event& event);
 
     /**
      * On successful connection.
@@ -204,11 +189,7 @@
      * \param irccd the irccd instance
      * \param event the event
      */
-    virtual void handle_connect(irccd& irccd, const connect_event& event)
-    {
-        (void)irccd;
-        (void)event;
-    }
+    virtual void handle_connect(irccd& irccd, const connect_event& event);
 
     /**
      * On disconnection.
@@ -216,11 +197,7 @@
      * \param irccd the irccd instance
      * \param event the event
      */
-    virtual void handle_disconnect(irccd& irccd, const disconnect_event& event)
-    {
-        (void)irccd;
-        (void)event;
-    }
+    virtual void handle_disconnect(irccd& irccd, const disconnect_event& event);
 
     /**
      * On invitation.
@@ -228,11 +205,7 @@
      * \param irccd the irccd instance
      * \param event the event
      */
-    virtual void handle_invite(irccd& irccd, const invite_event& event)
-    {
-        (void)irccd;
-        (void)event;
-    }
+    virtual void handle_invite(irccd& irccd, const invite_event& event);
 
     /**
      * On join.
@@ -240,11 +213,7 @@
      * \param irccd the irccd instance
      * \param event the event
      */
-    virtual void handle_join(irccd& irccd, const join_event& event)
-    {
-        (void)irccd;
-        (void)event;
-    }
+    virtual void handle_join(irccd& irccd, const join_event& event);
 
     /**
      * On kick.
@@ -252,21 +221,14 @@
      * \param irccd the irccd instance
      * \param event the event
      */
-    virtual void handle_kick(irccd& irccd, const kick_event& event)
-    {
-        (void)irccd;
-        (void)event;
-    }
+    virtual void handle_kick(irccd& irccd, const kick_event& event);
 
     /**
      * On load.
      *
      * \param irccd the irccd instance
      */
-    virtual void handle_load(irccd& irccd)
-    {
-        (void)irccd;
-    }
+    virtual void handle_load(irccd& irccd);
 
     /**
      * On channel message.
@@ -274,11 +236,7 @@
      * \param irccd the irccd instance
      * \param event the event
      */
-    virtual void handle_message(irccd& irccd, const message_event& event)
-    {
-        (void)irccd;
-        (void)event;
-    }
+    virtual void handle_message(irccd& irccd, const message_event& event);
 
     /**
      * On CTCP Action.
@@ -286,11 +244,7 @@
      * \param irccd the irccd instance
      * \param event the event
      */
-    virtual void handle_me(irccd& irccd, const me_event& event)
-    {
-        (void)irccd;
-        (void)event;
-    }
+    virtual void handle_me(irccd& irccd, const me_event& event);
 
     /**
      * On user mode change.
@@ -298,11 +252,7 @@
      * \param irccd the irccd instance
      * \param event the event
      */
-    virtual void handle_mode(irccd& irccd, const mode_event& event)
-    {
-        (void)irccd;
-        (void)event;
-    }
+    virtual void handle_mode(irccd& irccd, const mode_event& event);
 
     /**
      * On names listing.
@@ -310,11 +260,7 @@
      * \param irccd the irccd instance
      * \param event the event
      */
-    virtual void handle_names(irccd& irccd, const names_event& event)
-    {
-        (void)irccd;
-        (void)event;
-    }
+    virtual void handle_names(irccd& irccd, const names_event& event);
 
     /**
      * On nick change.
@@ -322,11 +268,7 @@
      * \param irccd the irccd instance
      * \param event the event
      */
-    virtual void handle_nick(irccd& irccd, const nick_event& event)
-    {
-        (void)irccd;
-        (void)event;
-    }
+    virtual void handle_nick(irccd& irccd, const nick_event& event);
 
     /**
      * On user notice.
@@ -334,11 +276,7 @@
      * \param irccd the irccd instance
      * \param event the event
      */
-    virtual void handle_notice(irccd& irccd, const notice_event& event)
-    {
-        (void)irccd;
-        (void)event;
-    }
+    virtual void handle_notice(irccd& irccd, const notice_event& event);
 
     /**
      * On part.
@@ -346,21 +284,14 @@
      * \param irccd the irccd instance
      * \param event the event
      */
-    virtual void handle_part(irccd& irccd, const part_event& event)
-    {
-        (void)irccd;
-        (void)event;
-    }
+    virtual void handle_part(irccd& irccd, const part_event& event);
 
     /**
      * On reload.
      *
      * \param irccd the irccd instance
      */
-    virtual void handle_reload(irccd& irccd)
-    {
-        (void)irccd;
-    }
+    virtual void handle_reload(irccd& irccd);
 
     /**
      * On topic change.
@@ -368,21 +299,14 @@
      * \param irccd the irccd instance
      * \param event the event
      */
-    virtual void handle_topic(irccd& irccd, const topic_event& event)
-    {
-        (void)irccd;
-        (void)event;
-    }
+    virtual void handle_topic(irccd& irccd, const topic_event& event);
 
     /**
      * On unload.
      *
      * \param irccd the irccd instance
      */
-    virtual void handle_unload(irccd& irccd)
-    {
-        (void)irccd;
-    }
+    virtual void handle_unload(irccd& irccd);
 
     /**
      * On whois information.
@@ -390,11 +314,7 @@
      * \param irccd the irccd instance
      * \param event the event
      */
-    virtual void handle_whois(irccd& irccd, const whois_event& event)
-    {
-        (void)irccd;
-        (void)event;
-    }
+    virtual void handle_whois(irccd& irccd, const whois_event& event);
 };
 
 /**
--- a/libirccd/irccd/daemon/service/plugin_service.cpp	Wed Jul 18 13:49:56 2018 +0200
+++ b/libirccd/irccd/daemon/service/plugin_service.cpp	Thu Jul 19 07:22:36 2018 +0200
@@ -53,11 +53,11 @@
 
 plugin_service::~plugin_service()
 {
-    for (const auto& [_, plugin] : plugins_) {
+    for (const auto& plg : plugins_) {
         try {
-            plugin->handle_unload(irccd_);
+            plg->handle_unload(irccd_);
         } catch (const std::exception& ex) {
-            irccd_.get_log().warning(*plugin) << ex.what() << std::endl;
+            irccd_.get_log().warning(*plg) << ex.what() << std::endl;
         }
     }
 }
@@ -67,32 +67,38 @@
     return plugins_;
 }
 
-auto plugin_service::has(const std::string& name) const noexcept -> bool
+auto plugin_service::has(std::string_view id) const noexcept -> bool
 {
-    return plugins_.find(name) != plugins_.end();
+    return get(id) != nullptr;
 }
 
-auto plugin_service::get(const std::string& name) const noexcept -> std::shared_ptr<plugin>
+auto plugin_service::get(std::string_view id) const noexcept -> std::shared_ptr<plugin>
 {
-    if (auto it = plugins_.find(name); it != plugins_.end())
-        return it->second;
+    const auto find = [id] (const auto& plg) {
+        return plg->get_id() == id;
+    };
+
+    if (const auto it = std::find_if(plugins_.begin(), plugins_.end(), find); it != plugins_.end())
+        return *it;
 
     return nullptr;
 }
 
-auto plugin_service::require(const std::string& name) const -> std::shared_ptr<plugin>
+auto plugin_service::require(std::string_view id) const -> std::shared_ptr<plugin>
 {
-    auto plugin = get(name);
+    auto plugin = get(id);
 
     if (!plugin)
-        throw plugin_error(plugin_error::not_found, name);
+        throw plugin_error(plugin_error::not_found, id);
 
     return plugin;
 }
 
-void plugin_service::add(std::string id, std::shared_ptr<plugin> plugin)
+void plugin_service::add(std::shared_ptr<plugin> plugin)
 {
-    plugins_.emplace(std::move(id), std::move(plugin));
+    assert(plugin);
+
+    plugins_.push_back(std::move(plugin));
 }
 
 void plugin_service::add_loader(std::unique_ptr<plugin_loader> loader)
@@ -102,17 +108,17 @@
     loaders_.push_back(std::move(loader));
 }
 
-auto plugin_service::get_options(const std::string& id) -> plugin::map
+auto plugin_service::get_options(std::string_view id) -> plugin::map
 {
     return to_map(irccd_.get_config(), str(format("plugin.%1%") % id));
 }
 
-auto plugin_service::get_formats(const std::string& id) -> plugin::map
+auto plugin_service::get_formats(std::string_view id) -> plugin::map
 {
     return to_map(irccd_.get_config(), str(format("format.%1%") % id));
 }
 
-auto plugin_service::get_paths(const std::string& id) -> plugin::map
+auto plugin_service::get_paths(std::string_view id) -> plugin::map
 {
     auto defaults = to_map(irccd_.get_config(), "paths");
     auto paths = to_map(irccd_.get_config(), str(format("paths.%1%") % id));
@@ -136,8 +142,7 @@
     return paths;
 }
 
-auto plugin_service::open(const std::string& id,
-                          const std::string& path) -> std::shared_ptr<plugin>
+auto plugin_service::open(std::string_view id, std::string_view path) -> std::shared_ptr<plugin>
 {
     for (const auto& loader : loaders_) {
         auto plugin = loader->open(id, path);
@@ -149,7 +154,7 @@
     return nullptr;
 }
 
-auto plugin_service::find(const std::string& id) -> std::shared_ptr<plugin>
+auto plugin_service::find(std::string_view id) -> std::shared_ptr<plugin>
 {
     for (const auto& loader : loaders_) {
         try {
@@ -165,7 +170,7 @@
     return nullptr;
 }
 
-void plugin_service::load(const std::string& id, const std::string& path)
+void plugin_service::load(std::string_view id, std::string_view path)
 {
     if (has(id))
         throw plugin_error(plugin_error::already_exists, id);
@@ -185,31 +190,35 @@
     plugin->set_paths(get_paths(id));
 
     exec(plugin, &plugin::handle_load, irccd_);
-    add(std::move(id), std::move(plugin));
+    add(std::move(plugin));
 }
 
-void plugin_service::reload(const std::string& name)
+void plugin_service::reload(std::string_view id)
 {
-    auto plugin = get(name);
+    auto plugin = get(id);
 
     if (!plugin)
-        throw plugin_error(plugin_error::not_found, name);
+        throw plugin_error(plugin_error::not_found, id);
 
     exec(plugin, &plugin::handle_reload, irccd_);
 }
 
-void plugin_service::unload(const std::string& id)
+void plugin_service::unload(std::string_view id)
 {
-    const auto it = plugins_.find(id);
+    const auto find = [id] (const auto& plg) {
+        return plg->get_id() == id;
+    };
+
+    const auto it = std::find_if(plugins_.begin(), plugins_.end(), find);
 
     if (it == plugins_.end())
         throw plugin_error(plugin_error::not_found, id);
 
     // Erase first, in case of throwing.
-    const auto plg = it->second;
+    const auto save = *it;
 
     plugins_.erase(it);
-    exec(plg, &plugin::handle_unload, irccd_);
+    exec(save, &plugin::handle_unload, irccd_);
 }
 
 void plugin_service::load(const config& cfg) noexcept
@@ -218,19 +227,19 @@
         if (!string_util::is_identifier(option.key()))
             continue;
 
-        auto name = option.key();
-        auto p = get(name);
+        auto id = option.key();
+        auto p = get(id);
 
         // Reload the plugin if already loaded.
         if (p) {
-            p->set_options(get_options(name));
-            p->set_formats(get_formats(name));
-            p->set_paths(get_paths(name));
+            p->set_options(get_options(id));
+            p->set_formats(get_formats(id));
+            p->set_paths(get_paths(id));
         } else {
             try {
-                load(name, option.value());
+                load(id, option.value());
             } catch (const std::exception& ex) {
-                irccd_.get_log().warning("plugin", name) << ex.what() << std::endl;
+                irccd_.get_log().warning("plugin", id) << ex.what() << std::endl;
             }
         }
     }
@@ -245,8 +254,7 @@
 
 auto loggable_traits<plugin>::get_component(const plugin& plugin) -> std::string_view
 {
-    // TODO: get id instead.
-    return plugin.get_name();
+    return plugin.get_id();
 }
 
 } // !logger
--- a/libirccd/irccd/daemon/service/plugin_service.hpp	Wed Jul 18 13:49:56 2018 +0200
+++ b/libirccd/irccd/daemon/service/plugin_service.hpp	Thu Jul 19 07:22:36 2018 +0200
@@ -28,7 +28,6 @@
 #include <memory>
 #include <string>
 #include <string_view>
-#include <unordered_map>
 #include <vector>
 
 #include <irccd/daemon/plugin.hpp>
@@ -47,7 +46,7 @@
     /**
      * \brief Map of plugins.
      */
-    using plugins = std::unordered_map<std::string, std::shared_ptr<plugin>>;
+    using plugins = std::vector<std::shared_ptr<plugin>>;
 
     /**
      * \brief List of loaders.
@@ -82,38 +81,36 @@
     /**
      * Check if a plugin is loaded.
      *
-     * \param name the plugin id
+     * \param id the plugin id
      * \return true if has plugin
      */
-    auto has(const std::string& name) const noexcept -> bool;
+    auto has(std::string_view id) const noexcept -> bool;
 
     /**
      * Get a loaded plugin or null if not found.
      *
-     * \param name the plugin id
+     * \param id the plugin id
      * \return the plugin or empty one if not found
      */
-    auto get(const std::string& name) const noexcept -> std::shared_ptr<plugin>;
+    auto get(std::string_view id) const noexcept -> std::shared_ptr<plugin>;
 
     /**
      * Find a loaded plugin.
      *
-     * \param name the plugin id
+     * \param id the plugin id
      * \return the plugin
      * \throw plugin_error on errors
      */
-    auto require(const std::string& name) const -> std::shared_ptr<plugin>;
+    auto require(std::string_view id) const -> std::shared_ptr<plugin>;
 
     /**
      * Add the specified plugin to the registry.
      *
-     * \pre id is valid
-     * \pre plugin != nullptr
-     * \param id the unique plugin identifier
-     * \param plugin the plugin
+     * \pre plg != nullptr
+     * \param plg the plugin
      * \note the plugin is only added to the list, no action is performed on it
      */
-    void add(std::string id, std::shared_ptr<plugin> plugin);
+    void add(std::shared_ptr<plugin> plg);
 
     /**
      * Add a loader.
@@ -126,25 +123,28 @@
     /**
      * Get the configuration for the specified plugin.
      *
+     * \param id the plugin id
      * \return the configuration
      */
-    auto get_options(const std::string& id) -> plugin::map;
+    auto get_options(std::string_view id) -> plugin::map;
 
     /**
      * Get the formats for the specified plugin.
      *
+     * \param id the plugin id
      * \return the formats
      */
-    auto get_formats(const std::string& id) -> plugin::map;
+    auto get_formats(std::string_view id) -> plugin::map;
 
     /**
      * Get the paths for the specified plugin.
      *
      * If none is defined, return the default ones.
      *
+     * \param id the plugin id
      * \return the paths
      */
-    auto get_paths(const std::string& id) -> plugin::map;
+    auto get_paths(std::string_view id) -> plugin::map;
 
     /**
      * Generic function for opening the plugin at the given path.
@@ -156,8 +156,7 @@
      * \param path the path to the file
      * \return the plugin or nullptr on failures
      */
-    auto open(const std::string& id,
-              const std::string& path) -> std::shared_ptr<plugin>;
+    auto open(std::string_view id, std::string_view path) -> std::shared_ptr<plugin>;
 
     /**
      * Generic function for finding a plugin.
@@ -165,7 +164,7 @@
      * \param id the plugin id
      * \return the plugin or nullptr on failures
      */
-    auto find(const std::string& id) -> std::shared_ptr<plugin>;
+    auto find(std::string_view id) -> std::shared_ptr<plugin>;
 
     /**
      * Convenient wrapper that loads a plugin, call handle_load and add it to
@@ -173,25 +172,26 @@
      *
      * Any errors are printed using logger.
      *
-     * \param name the name
+     * \param id the plugin id
      * \param path the optional path (searched if empty)
      */
-    void load(const std::string& name, const std::string& path = "");
+    void load(std::string_view name, std::string_view path = "");
 
     /**
      * Unload a plugin and remove it.
      *
+     * \param id the plugin id
      * \param name the plugin id
      */
-    void unload(const std::string& name);
+    void unload(std::string_view id);
 
     /**
      * Reload a plugin by calling onReload.
      *
-     * \param name the plugin name
+     * \param id the plugin id
      * \throw std::exception on failures
      */
-    void reload(const std::string& name);
+    void reload(std::string_view id);
 
     /**
      * Call a plugin function and throw an exception with the following errors:
--- a/libirccd/irccd/daemon/service/server_service.cpp	Wed Jul 18 13:49:56 2018 +0200
+++ b/libirccd/irccd/daemon/service/server_service.cpp	Thu Jul 19 07:22:36 2018 +0200
@@ -40,7 +40,7 @@
               EventNameFunc&& name_func,
               ExecFunc exec_func)
 {
-    for (auto& [_, plugin] : daemon.plugins().all()) {
+    for (const auto& plugin : daemon.plugins().all()) {
         const auto eventname = name_func(*plugin);
         const auto allowed = daemon.rules().solve(server, target, origin, plugin->get_name(), eventname);
 
--- a/plugins/links/links.cpp	Wed Jul 18 13:49:56 2018 +0200
+++ b/plugins/links/links.cpp	Thu Jul 19 07:22:36 2018 +0200
@@ -392,6 +392,8 @@
 
 class links_plugin : public plugin {
 public:
+    using plugin::plugin;
+
     auto get_name() const noexcept -> std::string_view override;
 
     auto get_author() const noexcept -> std::string_view override;
@@ -410,7 +412,7 @@
 
     static auto abi() -> version;
 
-    static auto init() -> std::unique_ptr<plugin>;
+    static auto init(std::string) -> std::unique_ptr<plugin>;
 };
 
 auto links_plugin::get_name() const noexcept -> std::string_view
@@ -461,9 +463,9 @@
     return version();
 }
 
-auto links_plugin::init() -> std::unique_ptr<plugin>
+auto links_plugin::init(std::string id) -> std::unique_ptr<plugin>
 {
-    return std::make_unique<links_plugin>();
+    return std::make_unique<links_plugin>(std::move(id));
 }
 
 BOOST_DLL_ALIAS(links_plugin::abi, irccd_abi_links)
--- a/tests/src/irccdctl/cli-plugin-config/main.cpp	Wed Jul 18 13:49:56 2018 +0200
+++ b/tests/src/irccdctl/cli-plugin-config/main.cpp	Thu Jul 19 07:22:36 2018 +0200
@@ -30,6 +30,8 @@
     map config_;
 
 public:
+    using plugin::plugin;
+
     auto get_name() const noexcept -> std::string_view override
     {
         return "config";
@@ -50,16 +52,16 @@
 public:
     configurable_plugin_cli_test()
     {
-        auto conf1 = std::make_unique<configurable_plugin>();
-        auto conf2 = std::make_unique<configurable_plugin>();
+        auto conf1 = std::make_unique<configurable_plugin>("conf1");
+        auto conf2 = std::make_unique<configurable_plugin>("conf2");
 
         conf1->set_options({
             { "v1", "123" },
             { "v2", "456" }
         });
 
-        irccd_.plugins().add("conf1", std::move(conf1));
-        irccd_.plugins().add("conf2", std::move(conf2));
+        irccd_.plugins().add(std::move(conf1));
+        irccd_.plugins().add(std::move(conf2));
     }
 };
 
--- a/tests/src/irccdctl/cli-plugin-info/main.cpp	Wed Jul 18 13:49:56 2018 +0200
+++ b/tests/src/irccdctl/cli-plugin-info/main.cpp	Thu Jul 19 07:22:36 2018 +0200
@@ -27,6 +27,11 @@
 
 class sample : public plugin {
 public:
+    sample()
+        : plugin("test")
+    {
+    }
+
     auto get_name() const noexcept -> std::string_view override
     {
         return "sample";
@@ -59,10 +64,10 @@
 {
     auto p = std::make_unique<sample>();
 
-    irccd_.plugins().add("p", std::move(p));
+    irccd_.plugins().add(std::move(p));
     start();
 
-    const auto result = exec({ "plugin-info", "p" });
+    const auto result = exec({ "plugin-info", "test" });
 
     BOOST_TEST(result.first.size() == 4U);
     BOOST_TEST(result.second.size() == 0U);
--- a/tests/src/irccdctl/cli-plugin-list/main.cpp	Wed Jul 18 13:49:56 2018 +0200
+++ b/tests/src/irccdctl/cli-plugin-list/main.cpp	Thu Jul 19 07:22:36 2018 +0200
@@ -27,6 +27,11 @@
 
 class sample : public plugin {
 public:
+    sample(std::string id)
+        : plugin(std::move(id))
+    {
+    }
+
     auto get_name() const noexcept -> std::string_view override
     {
         return "sample";
@@ -37,8 +42,8 @@
 
 BOOST_AUTO_TEST_CASE(output)
 {
-    irccd_.plugins().add("p1", std::make_unique<sample>());
-    irccd_.plugins().add("p2", std::make_unique<sample>());
+    irccd_.plugins().add(std::make_unique<sample>("p1"));
+    irccd_.plugins().add(std::make_unique<sample>("p2"));
     start();
 
     const auto result = exec({ "plugin-list" });
--- a/tests/src/irccdctl/cli-plugin-load/main.cpp	Wed Jul 18 13:49:56 2018 +0200
+++ b/tests/src/irccdctl/cli-plugin-load/main.cpp	Thu Jul 19 07:22:36 2018 +0200
@@ -27,6 +27,8 @@
 
 class sample : public plugin {
 public:
+    using plugin::plugin;
+
     auto get_name() const noexcept -> std::string_view override
     {
         return "sample";
@@ -40,14 +42,14 @@
     {
     }
 
-    auto find(std::string_view) -> std::shared_ptr<plugin> override
+    auto find(std::string_view id) -> std::shared_ptr<plugin> override
     {
-        return std::make_unique<sample>();
+        return std::make_unique<sample>(std::string(id));
     }
 
-    auto open(std::string_view, std::string_view) -> std::shared_ptr<plugin> override
+    auto open(std::string_view id, std::string_view) -> std::shared_ptr<plugin> override
     {
-        return std::make_unique<sample>();
+        return std::make_unique<sample>(std::string(id));
     }
 };
 
@@ -57,8 +59,8 @@
 
 BOOST_AUTO_TEST_CASE(simple)
 {
-    irccd_.plugins().add("p1", std::make_unique<sample>());
-    irccd_.plugins().add("p2", std::make_unique<sample>());
+    irccd_.plugins().add(std::make_unique<sample>("p1"));
+    irccd_.plugins().add(std::make_unique<sample>("p2"));
     irccd_.plugins().add_loader(std::make_unique<custom_plugin_loader>());
     start();
 
--- a/tests/src/irccdctl/cli-plugin-reload/main.cpp	Wed Jul 18 13:49:56 2018 +0200
+++ b/tests/src/irccdctl/cli-plugin-reload/main.cpp	Thu Jul 19 07:22:36 2018 +0200
@@ -29,6 +29,11 @@
 public:
     bool reloaded{false};
 
+    reloadable_plugin()
+        : plugin("test")
+    {
+    }
+
     auto get_name() const noexcept -> std::string_view override
     {
         return "reload";
@@ -46,10 +51,10 @@
 {
     const auto plugin = std::make_shared<reloadable_plugin>();
 
-    irccd_.plugins().add("p", plugin);
+    irccd_.plugins().add(plugin);
     start();
 
-    const auto result = exec({ "plugin-reload", "p" });
+    const auto result = exec({ "plugin-reload", "test" });
 
     BOOST_TEST(result.first.size() == 0U);
     BOOST_TEST(result.second.size() == 0U);
--- a/tests/src/irccdctl/cli-plugin-unload/main.cpp	Wed Jul 18 13:49:56 2018 +0200
+++ b/tests/src/irccdctl/cli-plugin-unload/main.cpp	Thu Jul 19 07:22:36 2018 +0200
@@ -29,6 +29,11 @@
 public:
     bool unloaded{false};
 
+    unloadable_plugin()
+        : plugin("test")
+    {
+    }
+
     auto get_name() const noexcept -> std::string_view override
     {
         return "unload";
@@ -46,10 +51,10 @@
 {
     const auto plugin = std::make_shared<unloadable_plugin>();
 
-    irccd_.plugins().add("p", plugin);
+    irccd_.plugins().add(plugin);
     start();
 
-    const auto result = exec({ "plugin-unload", "p" });
+    const auto result = exec({ "plugin-unload", "test" });
 
     BOOST_TEST(result.first.size() == 0U);
     BOOST_TEST(result.second.size() == 0U);
--- a/tests/src/libirccd-js/js-plugin/main.cpp	Wed Jul 18 13:49:56 2018 +0200
+++ b/tests/src/libirccd-js/js-plugin/main.cpp	Thu Jul 19 07:22:36 2018 +0200
@@ -39,7 +39,7 @@
 
     void load(std::string path)
     {
-        plugin_ = std::make_unique<js_plugin>(std::move(path));
+        plugin_ = std::make_unique<js_plugin>("test", std::move(path));
 
         irccd_jsapi().load(irccd_, plugin_);
         plugin_jsapi().load(irccd_, plugin_);
--- a/tests/src/libirccd/command-plugin-config/main.cpp	Wed Jul 18 13:49:56 2018 +0200
+++ b/tests/src/libirccd/command-plugin-config/main.cpp	Thu Jul 19 07:22:36 2018 +0200
@@ -32,6 +32,11 @@
 public:
     map config_;
 
+    custom_plugin()
+        : plugin("test")
+    {
+    }
+
     auto get_name() const noexcept -> std::string_view override
     {
         return "test";
@@ -52,7 +57,7 @@
 
 BOOST_AUTO_TEST_CASE(set)
 {
-    daemon_->plugins().add("test", std::make_unique<custom_plugin>());
+    daemon_->plugins().add(std::make_unique<custom_plugin>());
     ctl_->write({
         { "command",    "plugin-config" },
         { "plugin",     "test"          },
@@ -79,7 +84,7 @@
         { "x1", "10" },
         { "x2", "20" }
     });
-    daemon_->plugins().add("test", std::move(plugin));
+    daemon_->plugins().add(std::move(plugin));
 
     auto result = request({
         { "command",    "plugin-config" },
@@ -100,7 +105,7 @@
         { "x1", "10" },
         { "x2", "20" }
     });
-    daemon_->plugins().add("test", std::move(plugin));
+    daemon_->plugins().add(std::move(plugin));
 
     auto result = request({
         { "command", "plugin-config" },
--- a/tests/src/libirccd/command-plugin-info/main.cpp	Wed Jul 18 13:49:56 2018 +0200
+++ b/tests/src/libirccd/command-plugin-info/main.cpp	Thu Jul 19 07:22:36 2018 +0200
@@ -30,6 +30,11 @@
 
 class sample_plugin : public plugin {
 public:
+    sample_plugin()
+        : plugin("test")
+    {
+    }
+
     auto get_name() const noexcept -> std::string_view override
     {
         return "test";
@@ -63,7 +68,7 @@
     auto plg = std::make_unique<sample_plugin>();
     auto response = nlohmann::json();
 
-    daemon_->plugins().add("test", std::move(plg));
+    daemon_->plugins().add(std::move(plg));
 
     const auto result = request({
         { "command",    "plugin-info"       },
--- a/tests/src/libirccd/command-plugin-list/main.cpp	Wed Jul 18 13:49:56 2018 +0200
+++ b/tests/src/libirccd/command-plugin-list/main.cpp	Thu Jul 19 07:22:36 2018 +0200
@@ -30,6 +30,8 @@
 
 class sample_plugin : public plugin {
 public:
+    using plugin::plugin;
+
     auto get_name() const noexcept -> std::string_view override
     {
         return "sample";
@@ -40,8 +42,8 @@
 public:
     plugin_list_test()
     {
-        daemon_->plugins().add("t1", std::make_unique<sample_plugin>());
-        daemon_->plugins().add("t2", std::make_unique<sample_plugin>());
+        daemon_->plugins().add(std::make_unique<sample_plugin>("t1"));
+        daemon_->plugins().add(std::make_unique<sample_plugin>("t2"));
     }
 };
 
--- a/tests/src/libirccd/command-plugin-load/main.cpp	Wed Jul 18 13:49:56 2018 +0200
+++ b/tests/src/libirccd/command-plugin-load/main.cpp	Thu Jul 19 07:22:36 2018 +0200
@@ -30,6 +30,11 @@
 
 class broken : public plugin {
 public:
+    broken()
+        : plugin("broken")
+    {
+    }
+
     auto get_name() const noexcept -> std::string_view override
     {
         return "broken";
@@ -64,6 +69,8 @@
 
 class sample : public plugin {
 public:
+    using plugin::plugin;
+
     auto get_name() const noexcept -> std::string_view override
     {
         return "test";
@@ -85,7 +92,7 @@
     auto find(std::string_view id) noexcept -> std::shared_ptr<plugin> override
     {
         if (id == "test")
-            return std::make_unique<sample>();
+            return std::make_unique<sample>("test");
 
         return nullptr;
     }
@@ -97,7 +104,7 @@
     {
         daemon_->plugins().add_loader(std::make_unique<sample_loader>());
         daemon_->plugins().add_loader(std::make_unique<broken_loader>());
-        daemon_->plugins().add("already", std::make_unique<sample>());
+        daemon_->plugins().add(std::make_unique<sample>("already"));
     }
 };
 
--- a/tests/src/libirccd/command-plugin-reload/main.cpp	Wed Jul 18 13:49:56 2018 +0200
+++ b/tests/src/libirccd/command-plugin-reload/main.cpp	Thu Jul 19 07:22:36 2018 +0200
@@ -32,6 +32,11 @@
 public:
     bool reloaded{false};
 
+    reloadable_plugin()
+        : plugin("test")
+    {
+    }
+
     auto get_name() const noexcept -> std::string_view override
     {
         return "reload";
@@ -45,6 +50,11 @@
 
 class broken_plugin : public plugin {
 public:
+    broken_plugin()
+        : plugin("broken")
+    {
+    }
+
     auto get_name() const noexcept -> std::string_view override
     {
         return "broken";
@@ -63,8 +73,8 @@
     plugin_reload_test()
         : plugin_(std::make_shared<reloadable_plugin>())
     {
-        daemon_->plugins().add("test", plugin_);
-        daemon_->plugins().add("broken", std::make_unique<broken_plugin>());
+        daemon_->plugins().add(plugin_);
+        daemon_->plugins().add(std::make_unique<broken_plugin>());
     }
 };
 
--- a/tests/src/libirccd/command-plugin-unload/main.cpp	Wed Jul 18 13:49:56 2018 +0200
+++ b/tests/src/libirccd/command-plugin-unload/main.cpp	Thu Jul 19 07:22:36 2018 +0200
@@ -32,6 +32,11 @@
 public:
     bool unloaded{false};
 
+    unloadable_plugin()
+        : plugin("test")
+    {
+    }
+
     auto get_name() const noexcept -> std::string_view override
     {
         return "unload";
@@ -45,6 +50,11 @@
 
 class broken_plugin : public plugin {
 public:
+    broken_plugin()
+        : plugin("broken")
+    {
+    }
+
     auto get_name() const noexcept -> std::string_view override
     {
         return "broken";
@@ -63,8 +73,8 @@
     plugin_unload_test()
         : plugin_(std::make_shared<unloadable_plugin>())
     {
-        daemon_->plugins().add("test", plugin_);
-        daemon_->plugins().add("broken", std::make_unique<broken_plugin>());
+        daemon_->plugins().add(plugin_);
+        daemon_->plugins().add(std::make_unique<broken_plugin>());
     }
 };
 
--- a/tests/src/libirccd/dynlib-plugin/test_plugin.cpp	Wed Jul 18 13:49:56 2018 +0200
+++ b/tests/src/libirccd/dynlib-plugin/test_plugin.cpp	Thu Jul 19 07:22:36 2018 +0200
@@ -27,6 +27,11 @@
     map config_;
 
 public:
+    test_plugin()
+        : plugin("test")
+    {
+    }
+
     auto get_options() const -> map override
     {
         return config_;
@@ -127,7 +132,7 @@
         return version();
     }
 
-    static auto init() -> std::unique_ptr<plugin>
+    static auto init(std::string) -> std::unique_ptr<plugin>
     {
         return std::make_unique<test_plugin>();
     }
--- a/tests/src/plugins/plugin/main.cpp	Wed Jul 18 13:49:56 2018 +0200
+++ b/tests/src/plugins/plugin/main.cpp	Thu Jul 19 07:22:36 2018 +0200
@@ -37,6 +37,8 @@
 
 class fake_plugin : public plugin {
 public:
+    using plugin::plugin;
+
     auto get_name() const noexcept -> std::string_view override
     {
         return "fake";
@@ -68,7 +70,7 @@
     test_fixture()
         : plugin_test(PLUGIN_PATH)
     {
-        irccd_.plugins().add("fake", std::make_shared<fake_plugin>());
+        irccd_.plugins().add(std::make_shared<fake_plugin>("fake"));
 
         plugin_->set_formats({
             { "usage", "usage=#{plugin}:#{command}:#{server}:#{channel}:#{origin}:#{nickname}" },
@@ -133,7 +135,7 @@
 BOOST_AUTO_TEST_CASE(format_too_long)
 {
     for (int i = 0; i < 100; ++i)
-        irccd_.plugins().add(str(format("plugin-n-%1%") % i), std::make_shared<fake_plugin>());
+        irccd_.plugins().add(std::make_shared<fake_plugin>(str(format("plugin-n-%1%") % i)));
 
     plugin_->handle_command(irccd_, {server_, "jean!jean@localhost", "#staff", "list"});