# `Mutare.Options`
[🔗](https://github.com/foxbenjaminfox/mutare/blob/v0.2.1/lib/mutare/options.ex#L1)

Validated configuration for a mutation run.

`new/1` resolves a keyword list (or another `Options`) into a struct, validating every field up front. Invalid values raise `ArgumentError`. Passing the same options on the command line or in `.mutare.exs` uses the same validation; see `mix help mutare` for the full list of settable keys and their defaults.

Runtime wiring, such as the resolved `Mutare.Project` and live-progress hooks, lives in `Mutare.Run.Context`, not in this struct.

The fields and their types are listed in `t:t/0` below.

# `t`

```elixir
@type t() :: %Mutare.Options{
  argument_marks: [Mutare.Mutator.mark_declaration()],
  baseline_retries: non_neg_integer(),
  baseline_runs: pos_integer(),
  call_routes: list(),
  compile_timeout: pos_integer() | nil,
  confirm_timeouts: boolean(),
  exclude: [String.t()],
  expand_uses: boolean(),
  extensions: [Mutare.Extension.Spec.t()],
  fail_on_harness_error: boolean(),
  fail_on_poisoned: boolean(),
  harness_retries: non_neg_integer(),
  keep_sandbox: boolean(),
  kill_runs: pos_integer(),
  max_harness_error_rate: number() | nil,
  max_heap_mb: term(),
  max_mutants: pos_integer() | nil,
  max_no_coverage: non_neg_integer() | nil,
  max_survivors: pos_integer() | nil,
  min_score: number() | nil,
  mutators: [Mutare.Mutator.Spec.t()] | nil,
  only_files: MapSet.t() | nil,
  only_lines: MapSet.t() | nil,
  partition_env: String.t() | nil,
  paths: [String.t()],
  probe_timeout: pos_integer() | nil,
  quiet: boolean(),
  reporters: [{:human | :json | :html | :sarif, String.t() | nil}],
  sandbox: String.t() | nil,
  seed_app_build: boolean(),
  skip_lifting: MapSet.t(Mutare.Lifting.skip_entry()),
  strict_ignores: boolean(),
  test_selection: :tests | :coverage | :full,
  time_budget: String.t() | nil,
  timeout: pos_integer() | nil,
  timeout_multiplier: number(),
  verbose: boolean(),
  workers: pos_integer()
}
```

# `formats`

```elixir
@spec formats() :: [atom()]
```

The output formats a reporter entry may name (`:human`, `:json`, `:html`,
`:sarif`).

    iex> Mutare.Options.formats()
    [:human, :json, :html, :sarif]

# `new`

```elixir
@spec new(t() | keyword()) :: t()
```

Resolve and validate options.

Accepts a keyword list or an existing `Options` struct. Raises `ArgumentError`
on an unknown key or invalid value. `:workers` defaults to half
`System.schedulers_online/0` capped at 4 (each worker is a full `mix test`
BEAM that uses every scheduler, so the useful concurrency is a small constant,
not a fraction of the cores), resolved here so the struct carries a concrete
positive integer.

    iex> opts = Mutare.Options.new(
    ...>   paths: ["lib/billing"],
    ...>   workers: 2,
    ...>   mutators: [:arithmetic],
    ...>   reporters: [{:json, "mutare.json"}]
    ...> )
    iex> {opts.paths, opts.workers, Enum.map(opts.mutators, & &1.name), opts.reporters}
    {["lib/billing"], 2, [:arithmetic], [{:json, "mutare.json"}]}

    iex> opts = Mutare.Options.new(workers: 2)
    iex> Mutare.Options.new(opts) == opts
    true

# `renderer`

```elixir
@spec renderer(atom()) :: module()
```

The renderer module for an output `format`.

`:human` maps to `Mutare.Report`; machine formats map to modules under
`Mutare.Report.*`.

---

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