// file      : bpkg/pkg-status.cli
// license   : MIT; see accompanying LICENSE file

include <bpkg/configuration.cli>;

"\section=1"
"\name=bpkg-pkg-status"
"\summary=print package status"

namespace bpkg
{
  {
    "<options> <pkg> <ver>",

    // NOTE: remember to update <dep-spec> in bdep-status if changing the
    //       argument format.
    //
    "\h|SYNOPSIS|

     \c{\b{bpkg pkg-status}|\b{status} [<options>] [<pkg>[\b{/}<ver>]...]}

     \h|DESCRIPTION|

     The \cb{pkg-status} command prints the status of the specified packages
     or, if <ver> is specified, package versions. If no packages were
     specified, then \cb{pkg-status} prints the status of all the held
     packages (which are the packages that were explicitly built; see
     \l{bpkg-pkg-build(1)}). The latter mode can be modified to print the
     status of all the packages by specifying the \c{\b{--all}|\b{-a}} option.
     Additionally, the status of immediate or all dependencies of the above
     packages can be printed by specifying the \c{\b{--immediate}|\b{-i}} or
     \c{\b{--recursive}|\b{-r}} options, respectively. Note that the status is
     written to \cb{stdout}, not \cb{stderr}.

     The default output format (see the \cb{--stdout-format} common option) is
     regular with components separated with spaces. Each line starts with the
     package name followed by one of the status words listed below. Some of
     them can be optionally followed by '\cb{,}' (no spaces) and a sub-status
     word. Lines corresponding to dependencies from linked configurations will
     additionally mention the configuration directory in square brackets after
     the package name.

     \dl|

     \li|\cb{unknown}

         Package is not part of the configuration nor available from any of the
         repositories.|

     \li|\cb{available}

         Package is not part of the configuration but is available from one of
         the repositories.|

     \li|\cb{fetched}

         Package is part of the configuration and is fetched.|

     \li|\cb{unpacked}

         Package is part of the configuration and is unpacked.|

     \li|\cb{configured}

         Package is part of the configuration and is configured. May be
         followed by the \cb{system} sub-status indicating a package coming
         from the system. The version of such a system package (described
         below) may be the special '\cb{*}' value indicating a wildcard
         version.|

     \li|\cb{broken}

         Package is part of the configuration and is broken (broken packages
         can only be purged; see \l{bpkg-pkg-purge(1)}).||

     If only the package name was specified without the package version, then
     the \cb{available} status word is followed by the list of available
     versions. Versions that are only available for up/down-grading are
     printed in '\cb{[]}' (such version are only available as dependencies
     from prerequisite repositories of other repositories). If the
     \cb{--system} option is specified, then the last version in this list may
     have the \cb{sys:} prefix indicating an available system version. Such a
     system version may be the special '\cb{?}' value indicating that a
     package may or may not be available from the system and that its version
     is unknown.

     The \cb{fetched}, \cb{unpacked}, \cb{configured}, and \cb{broken} status
     words are followed by the version of the package. If the package version
     was specified, then the \cb{unknown} status word is also followed by the
     version.

     If the status is \cb{fetched}, \cb{unpacked}, \cb{configured}, or
     \cb{broken} and newer versions are available, then the package version is
     followed by the \cb{available} status word and the list of newer
     versions. To instead see a list of all versions, including the older
     ones, specify the \c{\b{--old-available}|\b{-o}} option. In this case the
     currently selected version is printed in '\cb{()}'.

     If the package name was specified with the version, then only the status
     (such as, \cb{configured}, \cb{available}, etc.) of this version is
     considered.

     If a package is being held, then its name is printed prefixed with
     '\cb{!}'. Similarly, if a package version is being held, then the version
     is printed prefixed with '\cb{!}'. Held packages and held versions were
     selected by the user and are not automatically dropped and upgraded,
     respectively.

     Below are some examples, assuming the configuration has \cb{libfoo}
     \cb{1.0.0} configured and held (both package and version) as well as
     \cb{libfoo} \cb{1.1.0} and \cb{1.1.1} available from source and
     \cb{1.1.0} from the system.

     \
     bpkg status libbar
     libbar unknown

     bpkg status libbar/1.0.0
     libbar unknown 1.0.0

     bpkg status libfoo/1.0.0
     !libfoo configured !1.0.0

     bpkg status libfoo/1.1.0
     libfoo available 1.1.0

     bpkg status --system libfoo/1.1.0
     libfoo available 1.1.0 sys:1.1.0

     bpkg status libfoo
     !libfoo configured !1.0.0 available 1.1.0 1.1.1

     bpkg status libfoo/1.1.1 libbar
     libfoo available 1.1.1
     libbar unknown
     \

     Assuming now that we dropped \cb{libfoo} from the configuration:

     \
     bpkg status libfoo/1.0.0
     libfoo unknown 1.0.0

     bpkg status libfoo
     libfoo available 1.1.0 1.1.1
     \

     And assuming now that we built \cb{libfoo} as a system package with
     the wildcard version:

     \
     bpkg status libfoo
     !libfoo configured,system !* available 1.1.0 1.1.1
     \

     Another example of the status output this time including dependencies:

     \
     bpkg status -r libbaz
     !libbaz configured 1.0.0
       libfoo configured 1.0.0
         bison [.bpkg/host/] configured 1.0.0
       libbar configured 2.0.0
     \

     If the output format is \cb{json}, then the output is a JSON array of
     objects which are the serialized representation of the following C++
     \cb{struct} \cb{package_status}:

     \
     struct available_version
     {
       string version;
       bool   system;
       bool   dependency;
     };

     struct package_status
     {
       string                    name;
       optional<string>          configuration;
       optional<string>          constraint;
       string                    status;
       optional<string>          sub_status;
       optional<string>          version;
       bool                      hold_package;
       bool                      hold_version;
       vector<available_version> available_versions;
       vector<package_status>    dependencies;
     };
     \

     For example:

     \
     [
       {
         \"name\": \"hello\",
         \"status\": \"configured\",
         \"version\": \"1.0.0\",
         \"hold_package\": true,
         \"available_versions\": [
           {
             \"version\": \"1.0.1\"
           },
           {
             \"version\": \"2.0.0\"
           }
         ],
         \"dependencies\": [
           {
             \"name\": \"libhello\",
             \"status\": \"configured\",
             \"version\": \"1.0.2\",
           }
         ]
       }
     ]
     \

     See the JSON OUTPUT section in \l{bpkg-common-options(1)} for details on
     the overall properties of this format and the semantics of the
     \cb{struct} serialization.

     In \cb{package_status}, the \cb{configuration} member contains the
     absolute directory of a linked configuration if this package resides in a
     linked configuration. The \cb{constraint} member is present only if the
     \cb{--constraint} option is specified. The \cb{version} member is absent
     if the \cb{status} member is \cb{unknown} or \cb{available} and no
     package version is specified on the command line. If the \cb{sub_status}
     member is \cb{system}, then the \cb{version} member can be special
     \cb{*}. The \cb{dependencies} member is present only if the
     \cb{--immediate|-i} or \cb{--recursive|-r} options are specified.

     In \cb{available_version}, if the \cb{system} member is \cb{true}, then
     this version is available from the system, in which case the \cb{version}
     member can be special \cb{?} or \cb{*}. If the \cb{dependency} member is
     \cb{true}, then this version is only available as a dependency from
     prerequisite repositories of other repositories.
     "
  }

  class pkg_status_options: configuration_options
  {
    "\h|PKG-STATUS OPTIONS|"

    bool --all|-a
    {
      "Print the status of all the packages, not just held."
    }

    bool --link
    {
      "Also print the status of held/all packages from linked configurations."
    }

    bool --immediate|-i
    {
      "Also print the status of immediate dependencies."
    }

    bool --recursive|-r
    {
      "Also print the status of all dependencies, recursively."
    }

    bool --old-available|-o
    {
      "Print old available versions."
    }

    bool --constraint
    {
      "Print version constraints for dependencies."
    }

    bool --system
    {
      "Check the availability of packages from the system."
    }

    bool --no-hold
    {
      "Don't print the package or version hold status."
    }

    bool --no-hold-package
    {
      "Don't print the package hold status."
    }

    bool --no-hold-version
    {
      "Don't print the version hold status."
    }
  };

  "
   \h|DEFAULT OPTIONS FILES|

   See \l{bpkg-default-options-files(1)} for an overview of the default
   options files. For the \cb{pkg-status} command the search start
   directory is the configuration directory. The following options files are
   searched for in each directory and, if found, loaded in the order listed:

   \
   bpkg.options
   bpkg-pkg-status.options
   \

   The following \cb{pkg-status} command options cannot be specified in the
   default options files:

   \
   --directory|-d
   \
  "
}
