# `mix composer.new`
[🔗](https://github.com/elixir-composer/composer/blob/v0.3.0/lib/mix/tasks/composer.new.ex#L1)

Creates an app with `igniter.new`, installs composer and a cookbook,
records the command line as the first commit, and runs a recipe.

    mix composer.new APP [REF] [RECIPE-FLAGS] [OPTIONS]

    mix composer.new my_app cb_lab:base/completions --with phx.new --with-args=--no-ecto
    mix composer.new my_app cb_lab:base/completions@github:elixir-composer/cb_lab@v0.3.0
    mix composer.new my_app cb_home:lv/base@path:~/src/Gen/cb_home --with phx.new
    mix composer.new my_app cb_mine:phx/saas --oban-pro --gigalixir

## REF

`COOKBOOK:GROUP/RECIPE[@SOURCE]`, where SOURCE says where the cookbook
comes from, as in `mix igniter.install`:

  * none - the latest Hex release
  * a version, `@0.3` or `@~> 0.3.1`
  * `@github:OWNER/REPO`, or `@github:OWNER/REPO@GITREF`
  * `@git:URL`
  * `@path:PATH`

REF must name its cookbook. `core:GROUP/RECIPE` takes no source, since
`core` ships with composer, and `hex:` refs aren't cookbooks. Without a
REF, the app gets composer only: run `mix composer.init` in it to start
your own cookbook.

## Options

  * `--with TASK` - the base generator, as in `igniter.new` (`phx.new`,
    ...); default `new`
  * `--with-args ARGS` - arguments for `--with`. Prefer the `=` form:
    `--with-args="--no-ecto --binary-id"`
  * `--install PKG[,PKG]` - base packages installed with the app, as
    prod deps (repeatable)
  * `--composer SOURCE` - where composer comes from (`path:...`,
    `github:...`, a version); default `~> <this archive's version>`
  * `--extra-dep PKG` - another dev/test dep, such as a second cookbook
    (repeatable)
  * `--igniter-local PATH` - a local igniter checkout, passed to
    `igniter.new --local` relative to the app's parent directory
  * `--reset` - delete APP first
  * `--dry-run` - print the plan and run nothing
  * `--no-recipe` - create, install and commit, but don't run the recipe

Every other switch is a recipe flag, passed on to
`mix composer.recipe.run`, which rejects any the recipe doesn't
declare. Everything after `--` is a recipe flag too. There is no
`--yes`: the command runs unattended.

## What it runs

The plan is printed first, every time; `--dry-run` stops there.

  1. `mix igniter.new APP --no-git --yes ...`, with `--with`,
     `--with-args`, `--install` and `--local`
  2. in APP, `mix igniter.install composer,COOKBOOK,... --only dev,test --yes`
  3. in APP, `git init`, `git add -A` and `git commit`, with this command
     line as the message: `git log --reverse` shows how to rebuild the app
  4. in APP, `mix composer.recipe.run COOKBOOK:GROUP/RECIPE [RECIPE-FLAGS]`,
     unless there is no REF or `--no-recipe` is given

## Recovery

The run stops at the first command that fails. If step 1 or 2 fails, APP
is partial: fix the problem and rerun with `--reset`. If the recipe
fails, APP is left at its generation commit, and the exact
`cd APP && mix composer.recipe.run ...` to retry is printed.

## A recipe is code

A cookbook from `@github:` or `@git:` runs someone else's code on your
machine, as `igniter.new --install` does. To look first, pass
`--no-recipe`, then run `mix composer.recipe.show REF` and
`mix composer.recipe.run REF --dry-run` in the app.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
