Add detailed help to channel linter

dependabot/npm_and_yarn/Src/WebController/UI/websocket-extensions-0.1.4
Grzegorz Rychlik 2020-02-19 15:04:37 +01:00
parent e0b253f6aa
commit 471ea7cc7a
6 changed files with 106 additions and 21 deletions

View File

@ -13,8 +13,14 @@ namespace MWR::C3::Linter
return m_ChannelArguments || m_Command || m_TestChannelIO;
}
/// Whether -h was set
bool m_ShowHelp = false;
/// Whether -l was set
bool m_ListChannels = false;
/// Channel name e.g. Slack
std::string m_ChannelName;
std::optional<std::string> m_ChannelName;
/// String representation of arguments passed to create a channel
std::optional<StringVector> m_ChannelArguments;

View File

@ -6,17 +6,22 @@ namespace MWR::C3::Linter
ArgumentParser::ArgumentParser(int argc, char** argv) : m_ArgParser()
{
ConfigureParser();
m_AppName = argv[0];
m_ArgParser.parse(argc, argv);
m_Config = CreateConfig();
FillConfig();
ValidateConfig();
}
void ArgumentParser::ConfigureParser()
{
m_ArgParser.addArgument("-n", "--name", 1, false);
m_ArgParser.addArgument("-h", "--help");
m_ArgParser.addArgument("-l", "--list");
m_ArgParser.addArgument("-n", "--name", 1);
m_ArgParser.addArgument("-a", "--args", '*');
m_ArgParser.addArgument("-c", "--complementary", '*');
m_ArgParser.addArgument("-i", "--test-io");
m_ArgParser.addArgument("-x", "--command", '+');
m_ArgParser.useExceptions(true);
}
AppConfig const& ArgumentParser::GetConfig() const
@ -26,31 +31,57 @@ namespace MWR::C3::Linter
std::string ArgumentParser::GetUsage() const
{
return m_ArgParser.usage();
return "Usage: " + m_AppName.filename().string() + R"( {-h|-l|-n NAME [options]}
Mode:
-h, --help Show this message and exit.
-l, --list List registered Channels and exit.
-n <NAME>, --name <NAME>
Select channel with given <NAME> for further processing
Options:
-a [ARGS...], --args [ARGS...]
Create channel with given ARGS using the Capability/create/arguments.
-c [ARGS...], --complementary [ARGS...]
Create a complementary channel with given ARGS.
-i, --test-io Create a pair of channels and send packets through.
If this option is present -a [ARGS...] must be specified.
If -c is not present, complementary channel arguments are deduced by swapping
parameters from Capability/create/arguments arrays.
-x <ID> [ARGS... ], --command <ID> [ARGS... ]
Execute a command with a given <ID> and arguments [ARGS...]
)";
}
MWR::C3::Linter::AppConfig ArgumentParser::CreateConfig() const
void ArgumentParser::FillConfig()
{
AppConfig config;
config.m_ChannelName = m_ArgParser.retrieve<std::string>("name");
m_Config.m_ShowHelp = m_ArgParser.exists("help");
m_Config.m_ListChannels = m_ArgParser.exists("list");
if (m_ArgParser.exists("name"))
m_Config.m_ChannelName = m_ArgParser.retrieve<std::string>("name");
if (m_ArgParser.exists("args"))
config.m_ChannelArguments = m_ArgParser.retrieve<std::vector<std::string>>("args");
m_Config.m_ChannelArguments = m_ArgParser.retrieve<std::vector<std::string>>("args");
if (m_ArgParser.exists("complementary"))
config.m_ComplementaryChannelArguments = m_ArgParser.retrieve<std::vector<std::string>>("complementary");
m_Config.m_ComplementaryChannelArguments = m_ArgParser.retrieve<std::vector<std::string>>("complementary");
config.m_TestChannelIO = m_ArgParser.exists("test-io");
m_Config.m_TestChannelIO = m_ArgParser.exists("test-io");
if (m_ArgParser.exists("command"))
config.m_Command = m_ArgParser.retrieve<StringVector>("command");
ValidateConfig();
return config;
m_Config.m_Command = m_ArgParser.retrieve<StringVector>("command");
}
void ArgumentParser::ValidateConfig() const
{
if(!(m_Config.m_ShowHelp || m_Config.m_ListChannels || m_Config.m_ChannelName))
throw std::invalid_argument("Argument error: either -h (--help), -l (--list) or -n (--name) must be specified");
if (m_Config.m_TestChannelIO && !m_Config.m_ChannelArguments)
throw std::invalid_argument("Argument error: specified -i (--test-io) without -a (--args)");

View File

@ -23,12 +23,15 @@ namespace MWR::C3::Linter
void ConfigureParser();
/// Helper create AppConfig
AppConfig CreateConfig() const;
void FillConfig();
/// Validate created config, uses ArgumentParser options in messages
/// @throws std::invalid_argument if config is not valid
void ValidateConfig() const;
/// place to store argv[0]
std::filesystem::path m_AppName;
/// Internal argument parser
argparse::ArgumentParser m_ArgParser;

View File

@ -70,7 +70,7 @@ namespace MWR::C3::Linter
ChannelLinter::ChannelLinter(AppConfig config) :
m_Config(std::move(config)),
m_ChannelData(GetChannelInfo(m_Config.m_ChannelName)),
m_ChannelData(GetChannelInfo(*m_Config.m_ChannelName)),
m_ChannelCapability(GetChannelCapability(m_ChannelData)),
m_CreateForm{ [this]
{

View File

@ -11,9 +11,26 @@ try
using namespace MWR;
C3::Linter::ArgumentParser argParser(argc, argv);
auto const& config = argParser.GetConfig();
std::cout << "Channel: " << config.m_ChannelName << std::endl;
if (config.m_ShowHelp)
{
std::cout << argParser.GetUsage() << std::endl;
return 0;
}
if (config.m_ListChannels)
{
auto const& channels = C3::InterfaceFactory::Instance().GetMap<C3::AbstractChannel>();
std::cout << "Registered channels: \n";
for (auto [hash, channelData] : channels)
std::cout << channelData.m_Name << '\n';
std::cout << std::flush;
return 0;
}
assert(config.m_ChannelName);
std::cout << "Channel: " << *config.m_ChannelName << std::endl;
auto channelLinter = C3::Linter::ChannelLinter(config);
std::cout << config.m_ChannelName << "'s Capability json verified OK." << std::endl;
std::cout << *config.m_ChannelName << "'s Capability json verified OK." << std::endl;
channelLinter.Process();
return 0;

View File

@ -1,11 +1,39 @@
# C3 Channel Linter
Standalone tool to ease the development and debugging of channels.
Tool to ease the development and debugging of channels.
Main goal is to provide a simple application to test channels without the need of spinning up the whole C3 network.
## Usage
This tool provides console frontend for channel usage
This tool provides console frontend for channel usage.
```
Usage: ChannelLinter.exe {-h|-l|-n NAME [options]}
Mode:
-h, --help Show this message and exit.
-l, --list List registered Channels and exit.
-n <NAME>, --name <NAME>
Select channel with given <NAME> for further processing
Options:
-a [ARGS...], --args [ARGS...]
Create channel with given ARGS using the Capability/create/arguments.
-c [ARGS...], --complementary [ARGS...]
Create a complementary channel with given ARGS.
-i, --test-io Create a pair of channels and send packets through.
If this option is present -a [ARGS...] must be specified.
If -c is not present, complementary channel arguments are deduced by swapping
parameters from Capability/create/arguments arrays.
-x <ID> [ARGS... ], --command <ID> [ARGS... ]
Execute a command with a given <ID> and arguments [ARGS...]
```
Example workflows:
1. Parse the json returned from `GetCapability()` and validate it against C3 rules:
`-n ChannelName`
`--name ChannelName`
@ -16,7 +44,7 @@ This tool provides console frontend for channel usage
`--args [Argument1 Argument2 ...]`
e.g. `ChannelLinter.exe -n UncShareFile --args inputId outputId C:\Temp\C3Store false`
Note: Messeges logged by calls to `this->Log()` will not be displayed if the channel constructor throws.
3. Test channel permeability - create a complemetary pair of channels and send message through.
3. Test channel permeability - create a complemetary pair of channels and send messages through.
`-i`
`--test-io`
e.g. `ChannelLinter.exe -n UncShareFile --args inputId outputId C:\Temp\C3Store false -i`