Mercurial > irccd
changeset 344:4665fffff6f2
Irccdctl: new cli interface
author | David Demelier <markand@malikania.fr> |
---|---|
date | Sat, 12 Nov 2016 22:58:48 +0100 |
parents | 3d927ba4af75 |
children | 006452e4a997 |
files | CMakeLists.txt irccd/main.cpp irccdctl/cli.cpp irccdctl/cli.hpp irccdctl/main.cpp plugins/debugnative/main.cpp |
diffstat | 6 files changed, 192 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- a/CMakeLists.txt Sat Nov 12 22:57:47 2016 +0100 +++ b/CMakeLists.txt Sat Nov 12 22:58:48 2016 +0100 @@ -91,7 +91,7 @@ add_subdirectory(contrib) if (WITH_JS) -#add_subdirectory(plugins) + add_subdirectory(plugins) endif () # Platform specific.
--- a/irccd/main.cpp Sat Nov 12 22:57:47 2016 +0100 +++ b/irccd/main.cpp Sat Nov 12 22:58:48 2016 +0100 @@ -35,6 +35,7 @@ #include <format.h> +#include "cmd-plugin-config.hpp" #include "cmd-plugin-reload.hpp" #include "cmd-plugin-unload.hpp" #include "cmd-server-cmode.hpp" @@ -297,6 +298,7 @@ option::Result options = parse(argc, argv); instance = std::make_unique<Irccd>(); + instance->commands().add(std::make_unique<command::PluginConfigCommand>()); instance->commands().add(std::make_unique<command::PluginReloadCommand>()); instance->commands().add(std::make_unique<command::PluginUnloadCommand>()); instance->commands().add(std::make_unique<command::ServerChannelModeCommand>());
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/irccdctl/cli.cpp Sat Nov 12 22:58:48 2016 +0100 @@ -0,0 +1,83 @@ +/* + * cli.cpp -- command line for irccdctl + * + * Copyright (c) 2013-2016 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <json.hpp> + +#include "cli.hpp" +#include "irccdctl.hpp" +#include "util.hpp" +#include "elapsed-timer.hpp" + +namespace irccd { + +void Cli::check(const nlohmann::json &response) +{ + if (!util::json::getBool(response, "status", false)) { + auto error = util::json::getString(response, "error"); + + if (error.empty()) + throw std::runtime_error("command failed with an unknown error"); + + throw std::runtime_error(error); + } +} + +nlohmann::json Cli::request(Irccdctl &irccdctl, nlohmann::json args) +{ + auto msg = nlohmann::json(); + + if (!args.is_object()) + args = nlohmann::json::object(); + + args.push_back({"command", m_name}); + irccdctl.client().request(args); + + auto id = irccdctl.client().onMessage.connect([&] (auto input) { + msg = std::move(input); + }); + + try { + ElapsedTimer timer; + + while (!msg.is_object() && timer.elapsed() < 3000) + util::poller::poll(3000 - timer.elapsed(), irccdctl); + } catch (const std::exception &) { + irccdctl.client().onMessage.disconnect(id); + throw; + } + + irccdctl.client().onMessage.disconnect(id); + + std::cout << msg << std::endl; + + if (!msg.is_object()) + throw std::runtime_error("no response received"); + if (util::json::getString(msg, "command") != m_name) + throw std::runtime_error("unexpected command result received"); + + check(msg); + + return msg; +} + +void Cli::call(Irccdctl &irccdctl, nlohmann::json args) +{ + check(request(irccdctl, args)); +} + +} // !irccd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/irccdctl/cli.hpp Sat Nov 12 22:58:48 2016 +0100 @@ -0,0 +1,98 @@ +/* + * cli.hpp -- command line for irccdctl + * + * Copyright (c) 2013-2016 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef IRCCD_CLI_HPP +#define IRCCD_CLI_HPP + +#include <string> +#include <vector> + +#include <json.hpp> + +namespace irccd { + +class Irccdctl; + +class Cli { +protected: + std::string m_name; + std::string m_summary; + std::string m_usage; + std::string m_help; + + /** + * Check the message result and print an error if any. + * + * \param result the result + * \throw an error if any + */ + void check(const nlohmann::json &result); + + /** + * Send a request and wait for the response. + * + * \param irccdctl the client + * \param args the optional arguments + */ + nlohmann::json request(Irccdctl &irccdctl, nlohmann::json args = nullptr); + + /** + * Call a command and wait for success/error response. + * + * \param irccdctl the client + * \param args the extra arguments (may be null) + */ + void call(Irccdctl &irccdctl, nlohmann::json args); + +public: + inline Cli(std::string name, std::string summary, std::string usage, std::string help) noexcept + : m_name(std::move(name)) + , m_summary(std::move(summary)) + , m_usage(std::move(usage)) + , m_help(std::move(help)) + { + } + + virtual ~Cli() = default; + + inline const std::string &name() const noexcept + { + return m_name; + } + + inline const std::string &summary() const noexcept + { + return m_summary; + } + + inline const std::string &usage() const noexcept + { + return m_usage; + } + + inline const std::string &help() const noexcept + { + return m_help; + } + + virtual void exec(Irccdctl &client, const std::vector<std::string> &args) = 0; +}; + +} // !irccd + +#endif // !IRCCD_CLI_HPP
--- a/irccdctl/main.cpp Sat Nov 12 22:57:47 2016 +0100 +++ b/irccdctl/main.cpp Sat Nov 12 22:58:48 2016 +0100 @@ -19,6 +19,7 @@ #include "client.hpp" #include "irccdctl.hpp" +#include "cli-plugin-config.hpp" #include "cli-plugin-reload.hpp" #include "cli-plugin-unload.hpp" #include "cli-server-cmode.hpp" @@ -46,8 +47,8 @@ Irccdctl ctl(std::make_unique<Client>()); ctl.client().connect(net::local::create("/tmp/irccd.sock")); - cli::ServerReconnectCli command; - command.exec(ctl, {"local"}); + cli::PluginConfigCli command; + command.exec(ctl, {"ask", "disable_if", "ok"}); } catch (const std::exception &ex) { std::cerr << ex.what() << std::endl; }
--- a/plugins/debugnative/main.cpp Sat Nov 12 22:57:47 2016 +0100 +++ b/plugins/debugnative/main.cpp Sat Nov 12 22:58:48 2016 +0100 @@ -18,11 +18,11 @@ #include <iostream> -#include <irccd/irccd.hpp> -#include <irccd/logger.hpp> -#include <irccd/plugin-dynlib.hpp> -#include <irccd/server.hpp> -#include <irccd/util.hpp> +#include <irccd.hpp> +#include <logger.hpp> +#include <plugin-dynlib.hpp> +#include <server.hpp> +#include <util.hpp> using namespace irccd;