lib/mix/tasks/needle.new.ex

defmodule Mix.Tasks.Needle.New do
  @moduledoc """
  Creates a new Phoenix project.

  It expects the path of the project as an argument.

      $ mix needle.new PATH [--app APP] [--module MODULE]

  A project at the given PATH will be created. The application name and module
  name will be retrieved from the path, unless `--app` or `--module` is given.


  ## Options

    * `--umbrella` - generates an umbrella project, which includes two
      applications, one for the domain, anotehr for the web interface.

    * `--app` - the name of the OTP application.

    * `--module` - the name of the base module in the generated skeleton.

    * `-v`, `--version` - prints the version.

  ### Context options

    * `--database` - specify the database adapter for Ecto. One of:

        * `postgres` - via https://github.com/elixir-ecto/postgrex
        * `mysql` - via https://github.com/elixir-ecto/myxql
        * `mssql` - via https://github.com/livehelpnow/tds
        * `sqlite3` - via https://github.com/elixir-sqlite/ecto_sqlite3

      Please check the driver docs for more information and requirements.
      Defaults to "postgres".

    * `--binary-id` - use `binary_id` as primary key type in Ecto schemas

    * `--no-ecto` - do not generate Ecto files.

    * `--no-mailer` - do not generate Swoosh mailer files.

  When passing the `--no-ecto` option, Needle generators such as
  `needle.gen.html`, `needle.gen.json`, `needle.gen.live`, and
  `needle.gen.context` may no longer work as expected as they
  generate context files that rely on Ecto for the database access.
  In those cases, you can pass the `--no-context` flag to generate most
  of the HTML and JSON files but skip the context, allowing you to fill
  in the blanks as desired.

  ### Web options

    * `--http-server` - specify the http server adapter. One of:
      * `cowboy` - via https://github.com/elixir-plug/plug_cowboy
      * `bandit` - via https://github.com/mtrudel/bandit

    Please check the adapter docs for more information and requirements.
    Defaults to "cowboy".

    * `--no-dashboard` - do not include Phoenix.LiveDashboard.

    * `--no-assets` - do not generate assets.

    * `--no-html` - do not generate HTML related files.

    * `--no-live` - do not generate LiveView related files.

  When passing the `--no-html` option, the files generated by `needle.gen.html`
  will no longer work, as important HTML components will be missing.

  ### Other options

    * `--no-gettext` - do not generate gettext files

  ## Examples

      $ mix needle.new hello_world

  which is equivalent to:

      $ mix needle.new hello_world --module HelloWorld

  ### create project without assets and HTML

      $ mix needle.new hello_world --no-assets --no-html

  which is useful to API projects.

  ### create an umbrella project

      $ mix needle.new hello_world --umbrella

  which generates the following directory structure and modules:

  ```
  hello_world_umbrella/   # HelloWorldUmbrella
    apps/
      hello_world/        # HelloWorld
      hello_world_web/    # HelloWorldWeb
  ```

  You can read more about umbrella projects using the
  official [Elixir guide](https://elixir-lang.org/getting-started/mix-otp/dependencies-and-umbrella-apps.html#umbrella-projects).
  """

  use Mix.Task

  alias Needle.New
  alias Needle.New.Generators.Single
  alias Needle.New.Generators.Umbrella

  @shortdoc "Creates a new Phoenix v#{New.phoenix_version()} project"

  @switches [
    umbrella: :boolean
  ]

  @impl true
  def run(argv) do
    {opts, _rest, _errors} = OptionParser.parse(argv, strict: @switches)

    generator = if opts[:umbrella], do: Umbrella, else: Single
    New.run(__MODULE__, argv, generator)
  end
end