# `Igniter.Project.Config`
[🔗](https://github.com/ash-project/igniter/blob/v0.8.2/lib/igniter/project/config.ex#L5)

Codemods and utilities for modifying Elixir config files.

# `after_predicate`

```elixir
@type after_predicate() :: (Sourceror.Zipper.t() -&gt; boolean())
```

# `config_group_item`

```elixir
@type config_group_item() ::
  {[term()] | term(), term()} | {[term()] | term(), term(), Keyword.t()}
```

# `on_scope_missing`

```elixir
@type on_scope_missing() ::
  :error
  | :skip
  | (Sourceror.Zipper.t() -&gt;
       {:ok, Sourceror.Zipper.t()}
       | :error
       | {:warning, String.t()}
       | {:error, String.t()})
```

# `updater`

```elixir
@type updater() ::
  (Sourceror.Zipper.t() -&gt; {:ok, Sourceror.Zipper.t()}) | :error | nil
```

# `configure`

```elixir
@spec configure(
  Igniter.t(),
  Path.t(),
  atom(),
  [atom()],
  term(),
  opts :: Keyword.t()
) :: Igniter.t()
```

Sets a config value in the given configuration file, updating it with `updater` if it is already set.

If the value is source code, pass `{:code, value}`, otherwise pass just the value.

To produce this source code, we suggest using `Sourceror.parse_string!`. For example:

```elixir
|> Igniter.Project.Config.configure(
  "fake.exs",
  :tailwind,
  [:default, :args],
  {:code,
   Sourceror.parse_string!("""
   ~w(--config=tailwind.config.js --input=css/app.css --output=../output/assets/app.css)
   """)}
)
```

## Options

* `failure_message` - A message to display to the user if the configuration change is unsuccessful.
* `updater` - `t:updater/0`. A function that takes a zipper at a currently configured value and returns a new zipper with the value updated.
* `after` - `t:after_predicate/0`. Moves to the last node that matches the predicate. Useful to guarantee a `config` is placed after a specific node.
* `env` - An atom like `:prod`. Scopes the configuration change to the matching `config_env()` block in the file.
* `in_scope` - Cursor patterns that scope where the configuration change is applied.
  See `Igniter.Code.Common.move_to_cursor_match_in_scope/2`.
* `on_scope_missing` - `t:on_scope_missing/0`. What to do when the scope cannot be found. Defaults to `:error`.

# `configure_group`

```elixir
@spec configure_group(
  Igniter.t(),
  Path.t(),
  atom(),
  shared_prefix :: [atom()],
  [config_group_item()],
  opts :: Keyword.t()
) :: Igniter.t()
```

Configures a "group" of configurations, which is multiple configurations set at one time.
If the app + the shared prefix is already configured, then each configuration is added individually,
and the `comment` for the group is ignored. The sub configurations use `configure`, so if you want to
not change the value if its already set, use `updater: &{:ok, &1}` in the item opts.

## Options

- `comment` - A comment string to add above the group when its added.

# `configure_new`

```elixir
@spec configure_new(
  Igniter.t(),
  Path.t(),
  atom(),
  [atom()],
  term(),
  opts :: Keyword.t()
) :: Igniter.t()
```

Sets a config value in the given configuration file, if it is not already set.

See `configure/6` for more.

## Options

* `failure_message` - A message to display to the user if the configuration change is unsuccessful.
* `after` - `t:after_predicate/0`. Moves to the last node that matches the predicate.
* `env` - An atom like `:prod`. Scopes the configuration change to the matching `config_env()` block.
* `in_scope` - Cursor patterns that scope where the configuration change is applied.
  See `Igniter.Code.Common.move_to_cursor_match_in_scope/2`.
* `on_scope_missing` - `t:on_scope_missing/0`. What to do when the scope cannot be found.
  Defaults to `:error`.

# `configure_runtime_env`

```elixir
@spec configure_runtime_env(
  Igniter.t(),
  atom(),
  atom(),
  [atom()],
  term(),
  opts :: Keyword.t()
) :: Igniter.t()
```

# `configures?`

> This function is deprecated. Use configures_root_key?/2 or configures_key?/3 instead..

```elixir
@spec configures?(Sourceror.Zipper.t(), [atom()], atom()) :: boolean()
```

# `configures?`

> This function is deprecated. Use configures_root_key?/3 or configures_key?/4 instead..

```elixir
@spec configures?(Igniter.t(), String.t(), [atom()], atom()) :: boolean()
```

Returns `true` if the given configuration path is set somewhere after the provided zipper, or in the given configuration file.

# `configures_key?`

```elixir
@spec configures_key?(Sourceror.Zipper.t(), atom(), atom() | [atom()]) :: boolean()
```

Same as `configures_key?/4` but accepts a Zipper.

# `configures_key?`

```elixir
@spec configures_key?(
  Igniter.t(),
  String.t(),
  atom(),
  atom() | [atom()]
) :: boolean()
```

If the last argument is key, checks if either `config :root_key, :key, ...`
or `config :root_key, key: ...` is set.

If the last argument is a keyword path, checks if
`config :root_key, path_head, [...]` defines `path_rest` or if
`config :root_key, [...]` defines `path`, where `path_head` is the first
element of `path` and `path_rest` are the remaining elements.

Note: `config_file_name` should _not_ include the `config/` prefix.

# `configures_root_key?`

```elixir
@spec configures_root_key?(Sourceror.Zipper.t(), atom()) :: boolean()
```

Same as `configures_root_key?/3` but accepts a Zipper instead.

# `configures_root_key?`

```elixir
@spec configures_root_key?(Igniter.t(), String.t(), atom()) :: boolean()
```

Checks if either `config :root_key, _` or `config :root_key, _, _` is present
in the provided config file.

Note: The config file name should _not_ include the `config/` prefix.

# `get_updater`

# `modify_config_code`

Modifies elixir configuration code starting at the configured zipper.

If you want to set configuration, use `configure/6` or `configure_new/5` instead. This is a lower-level
tool for modifying configuration files when you need to adjust some specific part of them.

## Options

* `updater` - `t:updater/0`. A function that takes a zipper at a currently configured value and returns a new zipper with the value updated.
* `after` - `t:after_predicate/0`. Moves to the last node that matches the predicate.

# `modify_configuration_code`

> This function is deprecated. Use `modify_config_code/5`.

```elixir
@spec modify_configuration_code(
  Sourceror.Zipper.t(),
  [atom()],
  atom(),
  term(),
  opts :: Keyword.t()
) :: Sourceror.Zipper.t()
@spec modify_configuration_code(
  Sourceror.Zipper.t(),
  [atom()],
  atom(),
  term(),
  opts :: Keyword.t()
) ::
  {:ok, Sourceror.Zipper.t()}
  | :error
  | {:warning, String.t()}
  | {:error, String.t()}
```

Modifies elixir configuration code starting at the configured zipper.

If you want to set configuration, use `configure/6` or `configure_new/5` instead. This is a lower-level
tool for modifying configuration files when you need to adjust some specific part of them.

## Options

* `updater` - `t:updater/0`. A function that takes a zipper at a currently configured value and returns a new zipper with the value updated.
* `after` - `t:after_predicate/0`. Moves to the last node that matches the predicate.

# `remove_application_configuration`

```elixir
@spec remove_application_configuration(Igniter.t(), Path.t(), atom()) :: Igniter.t()
```

Removes an applications config completely.

---

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