-
Notifications
You must be signed in to change notification settings - Fork 7.9k
feat(console): pass context to command handlers (IDFGH-16124) #17062
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
base: master
Are you sure you want to change the base?
Conversation
👋 Hello JVKran, we appreciate your contribution to this project! 📘 Please review the project's Contributions Guide for key guidelines on code, documentation, testing, and more. 🖊️ Please also make sure you have read and signed the Contributor License Agreement for this project. Click to see more instructions ...
Review and merge process you can expect ...
|
3ece38e
to
0a3ece0
Compare
Hello @JVKran , If I understand correctly, you want to be able to invoke a command with different parameters (context) than the one provided when registering the function, basically, overriding the default parameter. Is it correct? |
components/console/commands.c
Outdated
return esp_console_run_with_ctx(NULL, cmdline, cmd_ret); | ||
} | ||
|
||
esp_err_t esp_console_run_with_ctx(void* invocation_ctx, const char *cmdline, int *cmd_ret) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
esp_err_t esp_console_run_with_ctx(void* invocation_ctx, const char *cmdline, int *cmd_ret) | |
esp_err_t esp_console_run_with_context(void* invocation_ctx, const char *cmdline, int *cmd_ret) |
Since the type is named esp_console_cmd_func_with_context_t
, I would suggest to keep context
instead of ctx
, even
components/console/commands.c
Outdated
} | ||
if (cmd->func_w_context) { | ||
*cmd_ret = (*cmd->func_w_context)(cmd->context, argc, argv); | ||
*cmd_ret = (*cmd->func_w_context)(invocation_ctx, argc, argv); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
*cmd_ret = (*cmd->func_w_context)(invocation_ctx, argc, argv); | |
*cmd_ret = (*cmd->func_w_context)(invocation_ctx ?: cmd->context, argc, argv); |
I think this is what you meant, else the commands will never ne executed with their default context
components/console/esp_console.h
Outdated
* @brief Run command line with context | ||
* @param cmdline command line (command name followed by a number of arguments) | ||
* @param[out] cmd_ret return code from the command (set if command was run) | ||
* @param invocation_ctx pointer to context, can be used to pass additional data |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's more a context override rather than additional data
components/console/esp_console.h
Outdated
* - ESP_ERR_NOT_FOUND, if command with given name wasn't registered | ||
* - ESP_ERR_INVALID_STATE, if esp_console_init wasn't called | ||
*/ | ||
esp_err_t esp_console_run_with_context(void* invocation_ctx, const char* cmdline, int* cmd_ret); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the context is an optional parameter in this function, I think it'd make more sense to put it at the end
Hi @o-marshmallow, I've just incorporated your feedback. Thanks. |
@JVKran During an internal review, I was asked about the objective behind using a dynamic context. Because in theory, when a command is registered we already know what context it will be receiving when invoking the command via the console. The only dynamic behavior the command have would be through the And if let's say you have a request coming from HTTP and another other coming from |
Hi @o-marshmallow, The objective is the following;
Practically, in my main task, where MQTT payloads, HTTP requests and ESP-NOW packets are received, I can simply call esp_console_run to execute the command. What I want to establish is that I can provide three functions (with the same signature) as result outputs; This desired functionality isn't possible when the context is set during registration. The context set during registration is static, while I want it to be dynamic; they serve different purposes. Best regards, Jochem |
@JVKran I see why you would need a dynamic context in your case, but the question is why do you need to use a command for this? |
Because I literally need to expose a command line over these interfaces. I have around 30 commands that I need to expose over MQTT, HTTP, ESP-NOW and BLE-SPP. These interfaces must be available to literally do exactly what the otherwise useless I want these interfaces to be exactly the same to the users as the REPL's on UART and USB are, minus the logging itself. If I wouldn't be able to use this solution, I would need to not have 30 functions (for the command handlers), but 30 times the amount of interfaces. That's ridiculous. Take Zephyr's shell, for example. They provide a pointer to the shell so one can use shell_printf to print to the source command shell. I have no doubt that many others will be very happy if you were to provide an easier way to register logging backends (not just the printf that can be overriden) and would pass the source shell (the shell through which the command is issued) to the handler. This has always been a shortcoming in my opinion. If not, I feel like this dynamic context is a very reasonable and pragmatic solution. I dislike Zephyr in a lot of ways, but console/shell-wise, it's excellent. |
Thanks for the explanation, I understand what you mean. Can you please apply the changes I mentioned above so that I can open an internal merge request? (If you prefer I can also directly apply the changes myself on top of your PR when merging it internally) |
feat(console): pass context to command handlers feat(console): pass context to command handlers feat(console): pass context to command handlers Pass context to esp_console_run applied feedback Pre-commit hooks
Hi @o-marshmallow, I'm happy you understand. I've incorporated all changes you mentioned above and also used the pre-commit hooks. Is there anything else I can/need to assist you with? Best regards, Jochem |
sha=5fd9fb9e09b672429362c5be6b40df71424f59d7 |
@JVKran, I got some internal feedbacks, the console component is going to be deprecated in IDF since it will be completely refactored, so it wouldn't make a lot of sense to add a new feature to maintain. However, there is a simpler modification that would help you achieve what you need: make Thanks to it, you will be able to get the registered If you think this is acceptable, I will open an internal MR to make |
Description
One is now able to override the statically configured context with
esp_console_cmd_register
by calling the new functionesp_console_run_with_ctx
. I've taken a look at the original pull-request for the addition ofesp_console_cmd_func_with_context_t
and have reused the same context and function.Specifically, this is very useful when commands are received through (for example) MQTT, HTTP and ESP-NOW. It's great to be able to pass these backends so the command handlers can redirect output to those backends.
Testing
Changes have been tested in our existing code base. Changes are very basic and simple.
Checklist
Before submitting a Pull Request, please ensure the following: