// file      : bx/bx.cli
// license   : MIT; see accompanying LICENSE file

include <libbuild2/common.cli>;

"\section=1"
"\name=bx"
"\summary=shell script and task runner"

namespace build2
{
  {
    "<options> <path>, <task> <arg>",

    "\h|SYNOPSIS|

     \c{\b{bx} [<options>] <path> [<arg>...]\n
        \b{bx} [<options>] <task> [<arg>...]\n
        \b{bx} [<options>] [\b{--} <arg>...]}

     \h|DESCRIPTION|

     The \cb{build2} shell script and task runner executes a script (first
     form) or a task (second and third form) with optional arguments.

     The first argument after <options> determines whether it is a shell
     script path or a task name. It is considered a script if it contains
     the directory separator or the \cb{.bx} extension. Otherwise, it is
     considered a task name. Absent first argument means the default task.
     In this case the \cb{--} separator must be used if you wish to pass
     arguments to the default task. Note that neither the script path nor
     task name can start with \cb{-}.

     Note that task running is not yet implemented."
  }

  // @@ See @@ below regarding task running.

  // For usage it's nice to see the list of options on the first page. So
  // let's not put this "extended" description into usage.
  //
  {
    "",
    "",

    "The recommended first line (\"shebang\") for an executable script is as
     follows:

     \
     #! /usr/bin/env bx
     \

     "
  }

  class bx_options
  {
    "\h#options|OPTIONS|"

    uint64_t --build2-metadata; // Leave undocumented/hidden.

    bool -v
    {
      "Print actual commands being executed. This options is equivalent to
       \cb{--verbose 2}."
    }

    bool -V
    {
      "Print all underlying commands being executed. This options is
       equivalent to \cb{--verbose 3}."
    }

    bool --quiet|-q
    {
      "Run quietly, only printing error messages. This option is equivalent
       to \cb{--verbose 0}."
    }

    uint16_t --verbose = 1
    {
      "<level>",
      "Set the diagnostics verbosity to <level> between 0 and 6. Level 0
       disables any non-error messages while level 6 produces lots of
       information, with level 1 being the default. The following additional
       types of diagnostics are produced at each level:

       \ol|

       \li|High-level information messages.|

       \li|Essential underlying commands being executed.|

       \li|All underlying commands being executed.|

       \li|Information that could be helpful to the user.|

       \li|Information that could be helpful to the developer.|

       \li|Even more detailed information.||"
    }

    bool --diag-color
    {
      "Use color in diagnostics. If printing to a terminal the color is used
       by default provided the terminal is not dumb. Use \cb{--no-diag-color}
       to suppress."
    }

    bool --no-diag-color
    {
      "Don't use color in diagnostics."
    }

    size_t --max-stack
    {
      "<num>",
      "The maximum stack size in KBytes to allow for newly created threads.
       For \i{pthreads}-based systems the driver queries the stack size of
       the main thread and uses the same size for creating additional threads.
       This allows adjusting the stack size using familiar mechanisms, such
       as \cb{ulimit}. Sometimes, however, the stack size of the main thread
       is excessively large. As a result, the driver checks if it is greater
       than a predefined limit (64MB on 64-bit systems and 32MB on 32-bit
       ones) and caps it to a more sensible value (8MB) if that's the case.
       This option allows you to override this check with the special zero
       value indicating that the main thread stack size should be used as is."
    }

    string --pager // String to allow empty value.
    {
      "<path>",
      "The pager program to be used to show long text. Commonly used pager
       programs are \cb{less} and \cb{more}. You can also specify additional
       options that should be passed to the pager program with
       \cb{--pager-option}. If an empty string is specified as the pager
       program, then no pager will be used. If the pager program is not
       explicitly specified, then \cb{b} will try to use \cb{less}. If it
       is not available, then no pager will be used."
    }

    strings --pager-option
    {
      "<opt>",
      "Additional option to be passed to the pager program. See \cb{--pager}
       for more information on the pager program. Repeat this option to
       specify multiple pager options."
    }

    // The following option is "fake" in that it is actually handled by
    // argv_file_scanner. We have it here for documentation.
    //
    string --options-file
    {
      "<file>",
      "Read additional options from <file>. Each option should appear on a
       separate line optionally followed by space or equal sign (\cb{=}) and
       an option value. Empty lines and lines starting with \cb{#} are
       ignored. Option values can be enclosed in double (\cb{\"}) or single
       (\cb{'}) quotes to preserve leading and trailing whitespaces as well as
       to specify empty values. If the value itself contains trailing or
       leading quotes, enclose it with an extra pair of quotes, for example
       \cb{'\"x\"'}. Non-leading and non-trailing quotes are interpreted as
       being part of the option value.

       The semantics of providing options in a file is equivalent to providing
       the same set of options in the same order on the command line at the
       point where the \cb{--options-file} option is specified except that
       the shell escaping and quoting is not required. Repeat this option
       to specify more than one options file."
    }

    dir_path --default-options
    {
      "<dir>",
      "The directory to load additional default options files from."
    }

    bool --no-default-options
    {
      "Don't load default options files."
    }

    bool --help {"Print usage information and exit."}
    bool --version {"Print version and exit."}
  };

  "
  \h|DEFAULT OPTIONS FILES|

  Instead of having a separate config file format for tool configuration, the
  \cb{build2} toolchain uses \i{default options files} which contain the same
  options as what can be specified on the command line. The default options
  files are like options files that one can specify with \cb{--options-file}
  except that they are loaded by default.

  The default options files for \cb{bx} are called \cb{bx.options},
  \cb{bx-script.options} (shell script only), and \cb{bx-task.options} (task
  only) and are searched for in the \cb{.build2/} subdirectory of the home
  directory and in the system directory (for example, \cb{/etc/build2/}) if
  configured. Note that besides options the \cb{bx-task.options} file can
  also contain global variable overrides (@@ only for task running?).

  Once the search is complete, the files are loaded in the reverse order, that
  is, beginning from the system directory (if any), followed by the home
  directory, and finishing off with the options specified on the command line.
  For each directory \cb{bx.options}, if found, is loaded first, followed by
  \cb{bx-script.options} for a shell script and \cb{bx-task.options} for a
  task. In other words, the files are loaded from the more generic to the more
  specific with the command line options having the ability to override any
  values specified in the default options files.

  If a default options file contains \cb{--no-default-options}, then the
  search is stopped at the directory containing this file and no outer files
  are loaded. If this option is specified on the command line, then none of
  the default options files are searched for or loaded.

  An additional directory containing default options files can be specified
  with \cb{--default-options}. Its configuration files are loaded after the
  home directory.

  The order in which default options files are loaded is traced at the
  verbosity level 3 (\cb{-V} option) or higher.

  \h|EXIT STATUS|

  In case of a script execution, the script exit code is returned. In case
  of a task execution, non-zero exit status is returned in case of an error.
  "

  // NOTE: remember to update --build2-metadata output if adding any relevant
  //       new environment variables.
  //
  "
  \h|ENVIRONMENT|

  The \cb{HOME} environment variable is used to determine the user's home
  directory. If it is not set, then \cb{getpwuid(3)} is used instead. This
  value is used to shorten paths printed in diagnostics by replacing the home
  directory with \cb{~/}. It is also made available to scripts as the
  \cb{shell.home} variable.

  The \cb{BUILD2_DEF_OPT} environment variable is used to suppress loading of
  default options files in nested runner invocations. Its values are
  \cb{false} or \cb{0} to suppress and \cb{true} or \cb{1} to load.
  "
}
