python icon indicating copy to clipboard operation
python copied to clipboard

Discussion: command-line restructuring

Open ianmcorvidae opened this issue 1 year ago • 3 comments

Creating an issue for discussion of this in general.

Right now, the CLI is built around merely a long list of options, which is making it difficult to document and maintain which options go together and don't and sometimes leading to unexpected behavior (e.g. until recently, traceroutes were always sent on the primary channel, even if --ch-index was included).

While I think we will need to maintain support for the existing options for a while, it would be much better if we could create subcommands (and sub-subcommands, etc.) that more carefully split up the different things the CLI is able to do and including only arguments and options that make sense. This would also ensure the CLI is much more self-documenting, as opposed to the current --help output that mostly provides a very long list of things that only potentially work together. With such a system in place, the pre-existing options can also be reimplemented in terms of the more structured interface, which can in turn help in their ability to be automatically validated.

We should put together a fairly comprehensive plan for how we want the CLI to look. One inspiration might be the C# command line which already uses a structure somewhat like this: https://github.com/meshtastic/c-sharp

As I see it right now, the biggest overall categories are:

  • commands that read day-to-day information from the node without sending anything to the mesh, such as --nodes, --info, --device-metadata, and (somewhat) --listen, perhaps under something like an info subcommand
  • commands that involve administering nodes (both getting and setting), such as --configure, --export-config, --set, --get, --ch-set, --ch-add, --reboot, --shutdown, --factory-reset, --setlat/lon/alt, --pos-fields, --ch-longslow/etc., --seturl, --qr, --get-canned-message and --set-canned-message, and many more -- this is a lot of what the CLI is used for, but I think may still belong under an admin subcommand (with more subcommands below that, for certain)
  • commands that send or request things from the mesh, aside from administrative tasks, such as --sendtext, --traceroute, --request-telemetry, and --request-position. I'm not sure these all belong under the same subcommand; we might have a few like send and request with their own subcommands and shared implementation details (given that requests and traceroutes are, of course, also messages sent to the mesh)

As always, I don't claim any sort of special knowledge or insight here. I'd like to hear what others think so we can make the most comprehensible base we can. I'd also love to hear if there's features that others would like to see added. One that I've been working on somewhat is implementing a client proxy for MQTT.

Another thing we may at some point want to handle is that nodes only support a single connected client, so it could become valuable to implement some sort of "server mode" that maintains a single connection to a node but allows CLI commands to be directed at the server process. Luckily, that would probably just be its own subcommand in this structure, with a paired connection argument to connect to a server process.

Previously: #566

ianmcorvidae avatar May 09 '24 05:05 ianmcorvidae

I have no experience with the C# client. If its command line is good enough to access all features of the radio, we could do worse than go for compatibility?

holdenweb avatar May 09 '24 11:05 holdenweb

I don't have experience using it either, but looking at the github, the subcommands it has in place are:

list
monitor
live
info
get
set
channel <Add|Disable|Enable|Save>
url <Get|Set> <url>
reboot <seconds>
metadata
factory-reset
fixed-position <lat> <lon> <altitude>
text <message>
remove-node <nodenum>
reset-nodedb
trace-route
canned-messages <Get|Set> <messages>
waypoint <lat> <lon>
file <path>
update
export
import
mqtt-proxy
request-telemetry

with a handful of options: --port, --host, --output <Json|PrettyConsole>, -l/--log <level>, --dest <dest>, --sd/--select-dest, --version, and -?/-h/--help

I don't hate it (other than the Windows-y capitalization, but it's C# so that's expected), and while I don't think it does absolutely everything possible to do with the radio (remote hardware stuff comes to mind, for example) I'm sure it could be extended to do so with the structure it has (and it does a few things we currently can't, too).

However, when I'm using a CLI like this I tend to prefer a little less flat of a structure, instead having a first layer of subcommands for broader sorts of either actions to perform (so here, that would be things like send, request, admin, info, etc.) or objects to act on (which is a bit less intuitive here, I think, especially since most actions are ultimately acting on either a local or remote node, but docker is a good example with the first level being things like container, image, service etc.). That way, the help output either immediately answers "what sorts of actions can I perform" or "what sorts of things can I interact with", and then the help for each subcommand expands further. Things like having canned messages, URLs, and fixed positions being separate from the regular get/set feels weird. It's an artifact of how the admin messages work, of course, but it seems like it'd at least be a bit better if they're all under an admin subcommand to me.

I like the basic options structure as far as top-level stuff (we of course also support --ble).

What I'm not so sure of is whether I'm just a weird Linux nerd and this is incomprehensible to others. So I'm curious what others think.

One other thing to throw into the mix is if there's a good way to clearly communicate what things can be done remote or must be done locally by way of the structure (it feels like having separate remote-admin and local-admin that share most of their code would be ugly). If it can't be communicated by structure, it can at least be clearly documented what subcommands can act remotely or not.

ianmcorvidae avatar May 17 '24 23:05 ianmcorvidae

Another pattern i've seen in more modern clis include separating out +actions from --options. See the output of ghostty --help.

Usage: ghostty [+action] [options]

Run the Ghostty terminal emulator or a specific helper action.

If no `+action` is specified, run the Ghostty terminal emulator.
All configuration keys are available as command line options.
To specify a configuration key, use the `--<key>=<value>` syntax
where key and value are the same format you'd put into a configuration
file. For example, `--font-size=12` or `--font-family="Fira Code"`.

To see a list of all available configuration options, please see
the `src/config/Config.zig` file. A future update will allow seeing
the list of configuration options from the command line.

A special command line argument `-e <command>` can be used to run
the specific command inside the terminal emulator. For example,
`ghostty -e top` will run the `top` command inside the terminal.

On macOS, launching the terminal emulator from the CLI is not
supported and only actions are supported.

Available actions:

  +version
  +help
  +list-fonts
  +list-keybinds
  +list-themes
  +list-colors
  +list-actions
  +show-config
  +validate-config
  +crash-report
  +show-face

Specify `+<action> --help` to see the help for a specific action,
where `<action>` is one of actions listed below.

jedahan avatar Feb 16 '25 18:02 jedahan