edilmedeiros / rust-bcli

Bitcoin CLI in Rust
GNU General Public License v3.0
6 stars 2 forks source link

Design CLI user interface #5

Open edilmedeiros opened 6 months ago

edilmedeiros commented 6 months ago

We already know bitcoin-cli's interface.

See the README file for the proposed improvements.

See #4 for the selection of methods for the MVP. See #7 for the selection of command line options for the MVP.

Expected product: a specification of our command line interface, preferably in the form of documentation that will be presented to the user via the help command.

itornaza commented 6 months ago

My view on the specs are the following for our first version of the tool:

  1. The binary name of the command line tool shall be bitcoin (and keep bitcoind for the original deamon.)
  2. Long arguments could be accepted with --arg and short arguments with -a.
  3. Arguments and associated values shall be given in the common form, as: --datadir=foo and --datadir foo
  4. Values shall be passed as standard named arguments instead of as JSON.
edilmedeiros commented 6 months ago

bitcoin-cli defines its interface like this:

Usage:  bitcoin-cli [options] <command> [params]  Send command to Bitcoin Core
or:     bitcoin-cli [options] -named <command> [name=value]...  Send command to Bitcoin Core (with named arguments)
or:     bitcoin-cli [options] help                List commands
or:     bitcoin-cli [options] help <command>      Get help for a command

Using the getblockhash method as an example:

bitcoin-cli -named getblockhash height 0 is an error.

I'm thinking about defining our interface like so:

Usage:  btc [options] <command> [--name value]...  Send command to Bitcoin Core with named arguments
or:     btc [options] --legacy <command> [params]...  Send command to Bitcoin Core with positional arguments (possibly JSON)
or:     btc [options] man                Display list of commands
or:     btc [options] man <command>      Display manual page for a command

Points to discuss:

  1. The name of the executable. I like bcli more, but I propose btc because it is clearer and shorter.
  2. Rename the help command to man (for manual) so it does not clash with the --help option, which does a completely different thing.
  3. Introduce a --legacy option (or --compat) to defer to bitcoin-cli behavior. I'm unsure how useful this is and how much of a burden it will add to the code base. Alternatively, it could be btc [options] -- [legacy interface], and we take everything after -- and send it to bitcoin-cli without processing it (without using our internal RPC client, we just spaw a bitcoin-cli process with the given command line). This may add security issues, though.

In the getblockhash example, it would be

itornaza commented 6 months ago

I really like your analysis on the interface, it is thorough and addresses most of the interface issues!

  1. I would stick to bitcoin so it is harmonious with bitcoind
  2. I agree with the behavior you describe with the getblockhash example and consume only double dash arguments
  3. Despite I am a huge proponent of compatibility (foreword and backward), in this case I would not consider the --legacy option. This is a tool redesign and it is simple enough for anyone using the help methods to adapt to it in no time. If you really want to stick to it, why don't we consider it for a next version.
  4. For the interface, I would adjust it for not including the legacy if we decide like so, and put there a --help pointer so people get the full information upfront. Also, notice how bitcoin-cli, and bitcoin-cli --help produce the same output by dumping the options). If you want to use man instead of help, it does not do any difference for me as soon as it is consistent and the behavior for all of the man and help commands are displayed in the header.
Usage:  bitcoin [options] <command> [params]  Send command to Bitcoin Core
or:     bitcoin [options] --named <command> [name=value]...  Send command to Bitcoin Core (with named arguments)
or:     bitcoin [options] help                List commands
or:     bitcoin [options] help <command>      Get help for a command
or:     bitcoin [--help]                        List options
edilmedeiros commented 6 months ago
1. I would stick to `bitcoin` so it is harmonious with `bitcoind`

So, let's make it bitcoin.

2. I agree with the behavior you describe with the `getblockhash` example and consume only double dash arguments

👍

3. Despite I am a huge proponent of compatibility (foreword and backward), in this case I would not consider the --legacy option. This is a tool redesign and it is simple enough for anyone using the help methods to adapt to it in no time. If you really want to stick to it, why don't we consider it for a next version.

Actually, I don't like the --legacy idea myself. Now that you pointed, since this is a new tool I think we can be more opiniated in the design.

edilmedeiros commented 6 months ago
4. For the interface, I would adjust it for not including the legacy if we decide like so, and put there a `--help` pointer so people get the full information upfront. Also, notice how `bitcoin-cli`, and `bitcoin-cli --help` produce the same output by dumping the options). If you want to use man instead of help, it does not do any difference for me as soon as it is consistent and the behavior for all of the man and help commands are displayed in the header.
Usage:  bitcoin [options] <command> [params]  Send command to Bitcoin Core
or:     bitcoin [options] --named <command> [name=value]...  Send command to Bitcoin Core (with named arguments)
or:     bitcoin [options] help                List commands
or:     bitcoin [options] help <command>      Get help for a command
or:     bitcoin [--help]                        List options

The man command is not supposed to replace the --help option, but to have different names for semantically different objects. Let me clarify with the getblockhash example.

As you pointed out, bitcoin-cli alone will behave the same as bitcoin-cli --help, except for the error message in the end. Let's call this information, the help page.

$ bitcoin-cli      # behaves the same as bitcoin-cli --help with an additional error message in the end.
Bitcoin Core RPC client version v26.0

Usage:  bitcoin-cli [options] <command> [params]  Send command to Bitcoin Core
or:     bitcoin-cli [options] -named <command> [name=value]...  Send command to Bitcoin Core (with named arguments)
or:     bitcoin-cli [options] help                List commands
or:     bitcoin-cli [options] help <command>      Get help for a command

Options:
...
Error: too few parameters

Now consider bitcoin-cli --help getblockhash and bitcoin-cli help getblockhash.

In the first, we are setting the --help option which will igonre the getblockhash command and return the same help page as before.

$ bitcoin-cli --help getblockhash
Bitcoin Core RPC client version v26.0

Usage:  bitcoin-cli [options] <command> [params]  Send command to Bitcoin Core
or:     bitcoin-cli [options] -named <command> [name=value]...  Send command to Bitcoin Core (with named arguments)
or:     bitcoin-cli [options] help                List commands
or:     bitcoin-cli [options] help <command>      Get help for a command

Options:

In the later, we are not setting the --help option, but asking for the help command to do something.

$ bitcoin-cli help getblockhash
getblockhash height

Returns hash of block in best-block-chain at height provided.

Arguments:
1. height    (numeric, required) The height index

Result:
"hex"    (string) The block hash

Examples:
> bitcoin-cli getblockhash 1000
> curl --user myusername --data-binary '{"jsonrpc": "1.0", "id": "curltest", "method": "getblockhash", "params": [1000]}' -H 'content-type: text/plain;' http://127.0.0.1:8332/

I'm calling this last piece of information, the manual page for the getblockhash command.

I suggest having a --help option (as is usual in the GNU standard tooling people use as reference) and a separate man command (instead of the confusing help command). I got man in the spirit of GNU man pages.

itornaza commented 6 months ago

I suggest having a --help option (as is usual in the GNU standard tooling people use as reference) and a separate man command (instead of the confusing help command). I got man in the spirit of GNU man pages.

Since I am a GNU fanatic since 1996, agreed!

edilmedeiros commented 5 months ago

I'm dropping the man idea since clap already does a good job of automatically creating a help subcommand that does exactly what is needed.