Repository: bitcoin/bitcoin
File: src/bitcoin.cpp (C++)

Code before:
#else
#include <unistd.h>
#endif

extern const std::function<std::string(const char*)> G_TRANSLATION_FUN = nullptr;

static constexpr auto HELP_USAGE = R"(Usage: %1$s [OPTIONS] COMMAND...

Commands (run help command for more information):
  {gui,daemon,rpc,wallet,test,help}

Options:
  -m, --multiprocess     Run multiprocess binaries bitcoin-node, bitcoin-gui.\n"
  -M, --monolothic       Run monolithic binaries bitcoind, bitcoin-qt. (Default behavior)\n"
  -v, --version          Show version information
  -h, --help             Show this help message
)";

static constexpr auto HELP_COMMANDS = R"(Command overview:

%1$s gui [ARGS]     Start GUI, equivalent to running 'bitcoin-qt [ARGS]' or 'bitcoin-gui [ARGS]'.
%1$s daemon [ARGS]  Start daemon, equivalent to running 'bitcoind [ARGS]' or 'bitcoin-node [ARGS]'.
%1$s rpc [ARGS]     Call RPC method, equivalent to running 'bitcoin-cli -named [ARGS]'.
%1$s wallet [ARGS]  Call wallet command, equivalent to running 'bitcoin-wallet [ARGS]'.
%1$s tx [ARGS]      Manipulate hex-encoded transactions, equivalent to running 'bitcoin-tx [ARGS]'.
%1$s test [ARGS]    Run unit tests, equivalent to running 'test_bitcoin [ARGS]'.
%1$s help           Show this help message.
)";

struct CommandLine {
    bool use_multiprocess{false};
    bool show_version{false};
    bool show_help{false};
    std::string_view command;
    std::vector<std::string_view> args;
};

CommandLine ParseCommandLine(int argc, char* argv[]);
void ExecCommand(const std::vector<std::string>& args, std::string_view argv0);

int main(int argc, char* argv[])
{
    try {
        CommandLine cmd{ParseCommandLine(argc, argv)};
        if (cmd.show_version) {
            tfm::format(std::cout, "%s version %s\n%s", CLIENT_NAME, FormatFullVersion(), FormatParagraph(LicenseInfo()));
            return EXIT_SUCCESS;
        }
        if (cmd.show_help || cmd.command.empty()) {
            tfm::format(std::cout, HELP_USAGE, argv[0]);
        }

Review comment (suggestion):
Somehow I feel that `test` does not belong here - it is not for users to execute after the installation. `test_bitcoin` may not even be installed. The tests are normally run either by developers or by users after compile and before install, to verify the result of the compilation is correct.

Code after:

Options:
  -m, --multiprocess     Run multiprocess binaries bitcoin-node, bitcoin-gui.
  -M, --monolithic       Run monolithic binaries bitcoind, bitcoin-qt. (Default behavior)
  -v, --version          Show version information
  -h, --help             Show this help message

Commands:
  gui [ARGS]     Start GUI, equivalent to running 'bitcoin-qt [ARGS]' or 'bitcoin-gui [ARGS]'.
  node [ARGS]    Start node, equivalent to running 'bitcoind [ARGS]' or 'bitcoin-node [ARGS]'.
  rpc [ARGS]     Call RPC method, equivalent to running 'bitcoin-cli -named [ARGS]'.
  wallet [ARGS]  Call wallet command, equivalent to running 'bitcoin-wallet [ARGS]'.
  tx [ARGS]      Manipulate hex-encoded transactions, equivalent to running 'bitcoin-tx [ARGS]'.
  help [-a]      Show this help message. Include -a or --all to show additional commands.
)";

static constexpr auto HELP_EXTRA = R"(
Additional less commonly used commands:
  bench [ARGS]      Run bench command, equivalent to running 'bench_bitcoin [ARGS]'.
  chainstate [ARGS] Run bitcoin kernel chainstate util, equivalent to running 'bitcoin-chainstate [ARGS]'.
  test [ARGS]       Run unit tests, equivalent to running 'test_bitcoin [ARGS]'.
  test-gui [ARGS]   Run GUI unit tests, equivalent to running 'test_bitcoin-qt [ARGS]'.
)";

struct CommandLine {
    bool use_multiprocess{false};
    bool show_version{false};
    bool show_help{false};
    bool show_help_all{false};
    std::string_view command;
    std::vector<const char*> args;
};

CommandLine ParseCommandLine(int argc, char* argv[]);
static void ExecCommand(const std::vector<const char*>& args, std::string_view argv0);

int main(int argc, char* argv[])
{
    try {
        CommandLine cmd{ParseCommandLine(argc, argv)};
        if (cmd.show_version) {
            tfm::format(std::cout, "%s version %s\n%s", CLIENT_NAME, FormatFullVersion(), FormatParagraph(LicenseInfo()));
            return EXIT_SUCCESS;
        }

        std::vector<const char*> args;
        if (cmd.show_help || cmd.command.empty()) {
            tfm::format(std::cout, HELP_USAGE, argv[0]);
            if (cmd.show_help_all) tfm::format(std::cout, HELP_EXTRA);
            return cmd.show_help ? EXIT_SUCCESS : EXIT_FAILURE;
        } else if (cmd.command == "gui") {