Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add the ability to print help text for clusters to chip-tool. #26392

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions examples/chip-tool/commands/clusters/SubscriptionsCommands.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ class ShutdownAllSubscriptions : public CHIPCommand
private:
};

void registerClusterSubscriptions(Commands & commands, CredentialIssuerCommands * credsIssuerConfig)
void registerCommandsSubscriptions(Commands & commands, CredentialIssuerCommands * credsIssuerConfig)
{
const char * clusterName = "Subscriptions";

Expand All @@ -104,5 +104,5 @@ void registerClusterSubscriptions(Commands & commands, CredentialIssuerCommands
make_unique<ShutdownAllSubscriptions>(credsIssuerConfig), //
};

commands.Register(clusterName, clusterCommands);
commands.Register(clusterName, clusterCommands, "Commands for shutting down subscriptions.");
}
92 changes: 55 additions & 37 deletions examples/chip-tool/commands/common/Commands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,12 @@ static void DetectAndLogMismatchedDoubleQuotes(int argc, char ** argv)

} // namespace

void Commands::Register(const char * clusterName, commands_list commandsList)
void Commands::Register(const char * clusterName, commands_list commandsList, const char * helpText)
{
mClusters[clusterName].second = helpText;
for (auto & command : commandsList)
{
mClusters[clusterName].push_back(std::move(command));
mClusters[clusterName].first.push_back(std::move(command));
}
}

Expand Down Expand Up @@ -186,7 +187,6 @@ int Commands::RunInteractive(const char * command)

CHIP_ERROR Commands::RunCommand(int argc, char ** argv, bool interactive)
{
std::map<std::string, CommandsVector>::iterator cluster;
Command * command = nullptr;

if (argc <= 1)
Expand All @@ -196,29 +196,32 @@ CHIP_ERROR Commands::RunCommand(int argc, char ** argv, bool interactive)
return CHIP_ERROR_INVALID_ARGUMENT;
}

cluster = GetCluster(argv[1]);
if (cluster == mClusters.end())
auto clusterIter = GetCluster(argv[1]);
if (clusterIter == mClusters.end())
{
ChipLogError(chipTool, "Unknown cluster: %s", argv[1]);
ShowClusters(argv[0]);
return CHIP_ERROR_INVALID_ARGUMENT;
}

auto & commandList = clusterIter->second.first;
auto * clusterHelp = clusterIter->second.second;

if (argc <= 2)
{
ChipLogError(chipTool, "Missing command name");
ShowCluster(argv[0], argv[1], cluster->second);
ShowCluster(argv[0], argv[1], commandList, clusterHelp);
return CHIP_ERROR_INVALID_ARGUMENT;
}

bool isGlobalCommand = IsGlobalCommand(argv[2]);
if (!isGlobalCommand)
{
command = GetCommand(cluster->second, argv[2]);
command = GetCommand(commandList, argv[2]);
if (command == nullptr)
{
ChipLogError(chipTool, "Unknown command: %s", argv[2]);
ShowCluster(argv[0], argv[1], cluster->second);
ShowCluster(argv[0], argv[1], commandList, clusterHelp);
return CHIP_ERROR_INVALID_ARGUMENT;
}
}
Expand All @@ -227,15 +230,15 @@ CHIP_ERROR Commands::RunCommand(int argc, char ** argv, bool interactive)
if (argc <= 3)
{
ChipLogError(chipTool, "Missing event name");
ShowClusterEvents(argv[0], argv[1], argv[2], cluster->second);
ShowClusterEvents(argv[0], argv[1], argv[2], commandList);
return CHIP_ERROR_INVALID_ARGUMENT;
}

command = GetGlobalCommand(cluster->second, argv[2], argv[3]);
command = GetGlobalCommand(commandList, argv[2], argv[3]);
if (command == nullptr)
{
ChipLogError(chipTool, "Unknown event: %s", argv[3]);
ShowClusterEvents(argv[0], argv[1], argv[2], cluster->second);
ShowClusterEvents(argv[0], argv[1], argv[2], commandList);
return CHIP_ERROR_INVALID_ARGUMENT;
}
}
Expand All @@ -244,15 +247,15 @@ CHIP_ERROR Commands::RunCommand(int argc, char ** argv, bool interactive)
if (argc <= 3)
{
ChipLogError(chipTool, "Missing attribute name");
ShowClusterAttributes(argv[0], argv[1], argv[2], cluster->second);
ShowClusterAttributes(argv[0], argv[1], argv[2], commandList);
return CHIP_ERROR_INVALID_ARGUMENT;
}

command = GetGlobalCommand(cluster->second, argv[2], argv[3]);
command = GetGlobalCommand(commandList, argv[2], argv[3]);
if (command == nullptr)
{
ChipLogError(chipTool, "Unknown attribute: %s", argv[3]);
ShowClusterAttributes(argv[0], argv[1], argv[2], cluster->second);
ShowClusterAttributes(argv[0], argv[1], argv[2], commandList);
return CHIP_ERROR_INVALID_ARGUMENT;
}
}
Expand All @@ -271,7 +274,7 @@ CHIP_ERROR Commands::RunCommand(int argc, char ** argv, bool interactive)
return interactive ? command->RunAsInteractive() : command->Run();
}

std::map<std::string, Commands::CommandsVector>::iterator Commands::GetCluster(std::string clusterName)
Commands::ClusterMap::iterator Commands::GetCluster(std::string clusterName)
{
for (auto & cluster : mClusters)
{
Expand Down Expand Up @@ -342,14 +345,21 @@ void Commands::ShowClusters(std::string executable)
std::transform(clusterName.begin(), clusterName.end(), clusterName.begin(),
[](unsigned char c) { return std::tolower(c); });
fprintf(stderr, " | * %-82s|\n", clusterName.c_str());
ShowHelpText(cluster.second.second);
}
fprintf(stderr, " +-------------------------------------------------------------------------------------+\n");
}

void Commands::ShowCluster(std::string executable, std::string clusterName, CommandsVector & commands)
void Commands::ShowCluster(std::string executable, std::string clusterName, CommandsVector & commands, const char * helpText)
{
fprintf(stderr, "Usage:\n");
fprintf(stderr, " %s %s command_name [param1 param2 ...]\n", executable.c_str(), clusterName.c_str());

if (helpText)
{
fprintf(stderr, "\n%s\n", helpText);
}

fprintf(stderr, "\n");
fprintf(stderr, " +-------------------------------------------------------------------------------------+\n");
fprintf(stderr, " | Commands: |\n");
Expand Down Expand Up @@ -399,23 +409,7 @@ void Commands::ShowCluster(std::string executable, std::string clusterName, Comm
if (shouldPrint)
{
fprintf(stderr, " | * %-82s|\n", command->GetName());
const char * helpText = command->GetHelpText();
if (command->GetHelpText())
{
// We leave 82 chars for command names. The help text starts
// two chars further to the right, so there are 80 chars left
// for it.
if (strlen(helpText) > 80)
{
// Add "..." at the end to indicate truncation, and only
// show the first 77 chars, since that's what will fit.
fprintf(stderr, " | - %.77s...|\n", helpText);
}
else
{
fprintf(stderr, " | - %-80s|\n", helpText);
}
}
ShowHelpText(command->GetHelpText());
}
}
fprintf(stderr, " +-------------------------------------------------------------------------------------+\n");
Expand Down Expand Up @@ -541,16 +535,18 @@ bool Commands::DecodeArgumentsFromBase64EncodedJson(const char * json, std::vect
auto commandName = jsonValue[kJsonCommandKey].asString();
auto arguments = jsonValue[kJsonArgumentsKey].asString();

auto cluster = GetCluster(clusterName);
VerifyOrReturnValue(cluster != mClusters.end(), false,
auto clusterIter = GetCluster(clusterName);
VerifyOrReturnValue(clusterIter != mClusters.end(), false,
ChipLogError(chipTool, "Cluster '%s' is not supported.", clusterName.c_str()));

auto command = GetCommand(cluster->second, commandName);
auto & commandList = clusterIter->second.first;

auto command = GetCommand(commandList, commandName);

if (jsonValue.isMember(kJsonCommandSpecifierKey) && IsGlobalCommand(commandName))
{
auto commandSpecifierName = jsonValue[kJsonCommandSpecifierKey].asString();
command = GetGlobalCommand(cluster->second, commandName, commandSpecifierName);
command = GetGlobalCommand(commandList, commandName, commandSpecifierName);
}
VerifyOrReturnValue(nullptr != command, false, ChipLogError(chipTool, "Unknown command."));

Expand Down Expand Up @@ -602,3 +598,25 @@ bool Commands::DecodeArgumentsFromStringStream(const char * command, std::vector

return true;
}

void Commands::ShowHelpText(const char * helpText)
{
if (helpText == nullptr)
{
return;
}

// We leave 82 chars for command/cluster names. The help text starts
// two chars further to the right, so there are 80 chars left
// for it.
if (strlen(helpText) > 80)
{
// Add "..." at the end to indicate truncation, and only
// show the first 77 chars, since that's what will fit.
fprintf(stderr, " | - %.77s...|\n", helpText);
}
else
{
fprintf(stderr, " | - %-80s|\n", helpText);
}
}
13 changes: 9 additions & 4 deletions examples/chip-tool/commands/common/Commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,22 +30,24 @@ class Commands
public:
using CommandsVector = ::std::vector<std::unique_ptr<Command>>;

void Register(const char * clusterName, commands_list commandsList);
void Register(const char * clusterName, commands_list commandsList, const char * helpText = nullptr);
int Run(int argc, char ** argv);
int RunInteractive(const char * command);

private:
using ClusterMap = std::map<std::string, std::pair<CommandsVector, const char *>>;

CHIP_ERROR RunCommand(int argc, char ** argv, bool interactive = false);

std::map<std::string, CommandsVector>::iterator GetCluster(std::string clusterName);
ClusterMap::iterator GetCluster(std::string clusterName);
Command * GetCommand(CommandsVector & commands, std::string commandName);
Command * GetGlobalCommand(CommandsVector & commands, std::string commandName, std::string attributeName);
bool IsAttributeCommand(std::string commandName) const;
bool IsEventCommand(std::string commandName) const;
bool IsGlobalCommand(std::string commandName) const;

void ShowClusters(std::string executable);
void ShowCluster(std::string executable, std::string clusterName, CommandsVector & commands);
void ShowCluster(std::string executable, std::string clusterName, CommandsVector & commands, const char * helpText);
void ShowClusterAttributes(std::string executable, std::string clusterName, std::string commandName, CommandsVector & commands);
void ShowClusterEvents(std::string executable, std::string clusterName, std::string commandName, CommandsVector & commands);
void ShowCommand(std::string executable, std::string clusterName, Command * command);
Expand All @@ -54,7 +56,10 @@ class Commands
bool DecodeArgumentsFromBase64EncodedJson(const char * encodedData, std::vector<std::string> & args);
bool DecodeArgumentsFromStringStream(const char * command, std::vector<std::string> & args);

std::map<std::string, CommandsVector> mClusters;
// helpText may be null, in which case it's not shown.
static void ShowHelpText(const char * helpText);

ClusterMap mClusters;
#ifdef CONFIG_USE_LOCAL_STORAGE
PersistentStorage mStorage;
#endif // CONFIG_USE_LOCAL_STORAGE
Expand Down
2 changes: 2 additions & 0 deletions examples/chip-tool/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "commands/common/Commands.h"
#include "commands/example/ExampleCredentialIssuerCommands.h"

#include "commands/clusters/SubscriptionsCommands.h"
#include "commands/delay/Commands.h"
#include "commands/discover/Commands.h"
#include "commands/group/Commands.h"
Expand All @@ -45,6 +46,7 @@ int main(int argc, char * argv[])
registerCommandsTests(commands, &credIssuerCommands);
registerCommandsGroup(commands, &credIssuerCommands);
registerClusters(commands, &credIssuerCommands);
registerCommandsSubscriptions(commands, &credIssuerCommands);
registerCommandsStorage(commands);

return commands.Run(argc, argv);
Expand Down
2 changes: 0 additions & 2 deletions examples/chip-tool/templates/commands.zapt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
#include <commands/clusters/ComplexArgument.h>
#include <commands/clusters/ClusterCommand.h>
#include <commands/clusters/ReportCommand.h>
#include <commands/clusters/SubscriptionsCommands.h>
#include <commands/clusters/WriteAttributeCommand.h>

{{> clusters_header}}
Expand Down Expand Up @@ -146,5 +145,4 @@ void registerClusters(Commands & commands, CredentialIssuerCommands * credsIssue
{{#zcl_clusters}}
registerCluster{{asUpperCamelCase name}}(commands, credsIssuerConfig);
{{/zcl_clusters}}
registerClusterSubscriptions(commands, credsIssuerConfig);
}
2 changes: 1 addition & 1 deletion examples/tv-casting-app/linux/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ int main(int argc, char * argv[])
}

registerClusters(gCommands, &gCredIssuerCommands);
registerClusterSubscriptions(gCommands, &gCredIssuerCommands);
registerCommandsSubscriptions(gCommands, &gCredIssuerCommands);

if (argc > 1)
{
Expand Down
2 changes: 0 additions & 2 deletions zzz_generated/chip-tool/zap-generated/cluster/Commands.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.