// file      : bdep/init.cli
// license   : MIT; see accompanying LICENSE file

include <bdep/project.cli>;

"\section=1"
"\name=bdep-init"
"\summary=initialize project in build configurations"

namespace bdep
{
  {
    "<options>
     <prj-spec> <prj-dir>
     <pkg-spec> <pkg-dir>
     <cfg-spec> <cfg-name> <cfg-dir>
     <cfg-args> <bpkg-options> <module> <cfg-var>
     <pkg-args> <pkg>",

    "\h|SYNOPSIS|

     \c{\b{bdep init} [<options>] [<pkg-spec>] [<cfg-spec>] [<pkg-args>]\n
        \b{bdep init} [<options>] [<prj-spec>] \b{--empty|-E}\n
        \b{bdep init} [<options>] [<pkg-spec>] \b{--config-add|-A} <cfg-dir> [\b{@}<cfg-name>]\n
        \ \ \ \ \ \ \ \ \ \ [<pkg-args>]\n
        \b{bdep init} [<options>] [<pkg-spec>] \b{--config-create|-C} <cfg-dir> [\b{@}<cfg-name>]\n
        \ \ \ \ \ \ \ \ \ \ [<cfg-args>] [\b{--} <pkg-args>]}

     \c{<cfg-spec> = (\b{@}<cfg-name> | \b{--config}|\b{-c} <cfg-dir>)... | \b{--all}|\b{-a}\n
        <pkg-spec> = (\b{--directory}|\b{-d} <pkg-dir>)... | <prj-spec>\n
        <prj-spec> = \b{--directory}|\b{-d} <prj-dir>\n
        <pkg-args> = (\b{?}<pkg> | <cfg-var>)...\n
        <cfg-args> = [\b{--} [<bpkg-options>]] [\b{--existing}|\b{-e} | (<module> | <cfg-var>)...]}

     \h|DESCRIPTION|

     The \cb{init} command initializes a project in one or more build
     configurations. The first form initializes the specified project packages
     (<pkg-spec>), or, if the project itself is specified (<prj-spec>), all
     its available packages, in one or more build configurations (<cfg-spec>)
     that have already been associated with the project (\l{bdep-config(1)}).

     If no project directory is specified, then the current working directory
     is assumed. If no configuration is specified, then the default
     configuration is assumed (failing if multiple default configurations are
     present). Note that unlike in all other commands, in \cb{init} the
     package to initialize in <pkg-spec> cannot be specified as a <pkg> name,
     only as a directory with \c{\b{--directory}|\b{-d}}. See
     \l{bdep-projects-configs(1)} for details on specifying projects and
     configurations. Optional <pkg-args> are the additional dependency
     packages and/or configuration variables to pass to the underlying
     \l{bpkg-pkg-build(1)} command.

     The second form (\cb{--empty} is specified) initializes an empty project
     database that can later be used to first add build configurations
     (\l{bdep-config(1)}) and then initialize project packages using the first
     form.

     The third (\cb{--config-add}) and fourth (\cb{--config-create}) forms are
     shortcuts to first adding an existing or newly created build
     configuration and then initializing project packages in that
     configuration. Semantically they are equivalent to first performing the
     \cb{config add} or \cb{config create} commands (\l{bdep-config(1)}),
     respectively, followed by the first form. Optional <cfg-args> in the
     fourth form are the additional arguments to the underlying
     \l{bpkg-cfg-create(1)} command. Note that in this case to specify
     <pkg-args> without specifying <cfg-args> you have to use two \cb{--}
     separators, for example:

     \
     $ bdep init -C ../prj-gcc @gcc -- -- ?sys:libsqlite3/*
     \

     Configuration variables can be specified to only apply to specific
     packages in <pkg-args> using the argument grouping mechanism
     (\l{bdep-argument-grouping(1)}). Additionally, such packages can be
     placed into specific linked configurations by specifying the
     configuration with one of the \cb{--config*} options (or \cb{@} notation)
     using the same grouping mechanism. For example (assuming \cb{gcc} is
     linked to \cb{common}):

     \
     $ bdep init @gcc { @common config.liblarge.extra=true }+ ?liblarge
     \

     \h|EXAMPLES|

     As an example, consider project \cb{prj} with two packages, \cb{foo}
     and \cb{libfoo}:

     \
     prj/
    ├── foo/
    └── libfoo/
     \

     The following invocations illustrate the common \cb{init} use cases (the
     current working directory is shown before the shell prompt).

     Create new build configuration in \cb{../prj-gcc}, call it \cb{gcc}, and
     initialize project packages \cb{foo} and \cb{libfoo} in this
     configuration:

     \
     prj/$ bdep init -C ../prj-gcc @gcc cc config.cxx=g++
     \

     Create new build configuration in \cb{../prj-clang} using
     \l{bpkg-cfg-create(1)}. Then add it calling it \cb{clang} and initialize
     project package \cb{foo} in this configuration:

     \
     prj/$ bpkg create -d ../prj-clang cc config.cxx=clang++
     prj/$ cd foo
     foo/$ bdep init -A ../../prj-clang @clang
     \

     Initialize project package \cb{libfoo} in the build configuration
     \cb{clang}:

     \
     foo/$ cd ..
     prj/$ bdep init -d libfoo @clang
     \

     To additionally configure \cb{libfoo} add configuration variables to the
     above command line:

     \
     prj/$ bdep init -d libfoo @clang config.libfoo.bar=true
     \

     The following set of invocations achieves the same end result but using
     the \l{bdep-config(1)} command to manage configurations and
     \l{bdep-sync(1)} command to reconfigure a package.

     Initialize an empty project database:

     \
     prj/$ bdep init --empty
     \

     Create new build configuration in \cb{../prj-gcc}, call it \cb{gcc}:

     \
     prj/$ bdep config create ../prj-gcc @gcc cc config.cxx=g++
     \

     Add existing build configuration in \cb{../prj-clang}, call it
     \cb{clang}:

     \
     prj/$ bdep config add ../prj-clang @clang
     \

     Initialize project packages \cb{foo} and \cb{libfoo} in build
     configurations \cb{gcc} and \cb{clang}:

     \
     prj/$ bdep init @gcc @clang
     \

     Or, alternatively, in all the build configurations:

     \
     prj/$ bdep init -a
     \

     Reconfigure \cb{libfoo} in the build configuration \cb{clang}:

     \
     prj/$ bdep sync libfoo @clang config.libfoo.bar=true
     \
     "
  }

  class cmd_init_options: configuration_add_options, project_options
  {
    "\h|INIT OPTIONS|"

    bool --empty|-E
    {
      "Initialize an empty build configuration set."
    }

    dir_path --config-add|-A
    {
      "<dir>",
      "Add an existing build configuration <dir>."
    }

    dir_path --config-create|-C
    {
      "<dir>",
      "Create a new build configuration in <dir>."
    }

    bool --no-sync
    {
      "Enter the project into the database but do not initialize it in the
       build configurations. The initialization can be finished later with
       an explicit \l{bdep-sync(1)} command."
    }

    bool --sys-no-query
    {
      "Do not query the system package manager for the installed versions of
       packages specified with the \cb{sys} scheme. See the corresponding
       \l{bpkg-pkg-build(1)} option for details."
    }

    bool --sys-install
    {
      "Instruct the system package manager to install available versions of
       packages specified with the \cb{sys} scheme that are not already
       installed. See the corresponding \l{bpkg-pkg-build(1)} option for
       details."
    }

    bool --sys-no-fetch
    {
      "Do not fetch the system package manager metadata before querying for
       available versions of packages specified with the \cb{sys} scheme. See
       the corresponding \l{bpkg-pkg-build(1)} option for details."
    }

    bool --sys-no-stub
    {
      "Do no require a stub for packages specified with the \cb{sys} scheme.
       See the corresponding \l{bpkg-pkg-build(1)} option for details."
    }

    bool --sys-yes
    {
      "Assume the answer to the system package manager prompts is \cb{yes}.
       See the corresponding \l{bpkg-pkg-build(1)} option for details."
    }

    string --sys-sudo = "sudo"
    {
      "<prog>",
      "The \cb{sudo} program to use for system package manager interactions
       that normally require administrative privileges (fetch package
       metadata, install packages, etc). See the corresponding
       \l{bpkg-pkg-build(1)} option for details."
    }

    bool --create-host-config
    {
      "Create a configuration for build-time dependencies without prompt (see
       \l{bdep-sync(1)} for details)."
    }

    bool --create-build2-config
    {
      "Create a configuration for build system module dependencies without
       prompt (see \l{bdep-sync(1)} for details)."
    }
  };

  "
   \h|DEFAULT OPTIONS FILES|

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

   \
   bdep.options
   bdep-{config config-add}.options                # if --config-add|-A
   bdep-{config config-add config-create}.options  # if --config-create|-C
   bdep-init.options
   \

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

   \
   --directory|-d
   --config-add|-A
   --config-create|-C
   --wipe
   \
  "
}
