View Source Igniter (igniter v0.5.0)

Tools for generating and patching code into an Elixir project.

Summary

Functions

Adds an issue to the issues list. Any issues will prevent writing and be displayed to the user.

Adds a notice to the notices list. Notices are displayed to the user once the igniter finishes running.

Adds a task to the tasks list. Tasks will be run after all changes have been commited

Adds a warning to the warnings list. Warnings will not prevent writing, but will be displayed to the user.

Applies the current changes to the mix.exs in the Igniter and fetches dependencies.

Stores the key/value pair in igniter.assigns

Returns true if the igniter or source provided has changed

Returns true if any of the files specified in paths have changed.

Finds the Igniter.Mix.Task task by name and composes it with igniter.

Copies an EEx template file from the source path to the target path.

Creates a new file in the project with the provided string contents. Adds an error if it already exists.

Creates the given file in the project with the provided string contents, or updates it with a function of type zipper_updater() if it already exists.

Creates the given file in the project with the provided string contents, or updates it with a function as in update_file/3 (or with zipper_updater() for elixir files) if it already exists.

Executes or dry-runs a given Igniter.

Checks if a file exists on the file system or in the igniter.

Returns whether the current Igniter has pending changes.

This function stores in the igniter if its been run before, so it is only run once, which is expensive.

Includes the given file in the project, expecting it to exist. Does nothing if its already been added.

Includes all files matching the given glob, expecting them all (for now) to be elixir files.

Includes or creates the given file in the project with the provided contents. Does nothing if its already been added.

Creates a folder in the project.

Returns a new igniter

Runs an update over all elixir files

Updates the source code of the given elixir file

Updates all files matching the given glob with the given zipper function.

Types

t()

@type t() :: %Igniter{
  args: Igniter.Mix.Task.Args.t(),
  assigns: map(),
  issues: [String.t()],
  mkdirs: [String.t()],
  moves: %{optional(String.t()) => String.t()},
  notices: [String.t()],
  rewrite: Rewrite.t(),
  tasks: [String.t() | {String.t(), [String.t()]}],
  warnings: [String.t()]
}

zipper_updater()

@type zipper_updater() :: (Sourceror.Zipper.t() ->
                       {:ok, Sourceror.Zipper.t()}
                       | {:error, String.t() | [String.t()]}
                       | {:warning, String.t() | [String.t()]})

Functions

add_issue(igniter, issue)

@spec add_issue(t(), term() | [term()]) :: t()

Adds an issue to the issues list. Any issues will prevent writing and be displayed to the user.

add_notice(igniter, notice)

@spec add_notice(t(), String.t()) :: t()

Adds a notice to the notices list. Notices are displayed to the user once the igniter finishes running.

add_task(igniter, task, argv \\ [])

Adds a task to the tasks list. Tasks will be run after all changes have been commited

add_warning(igniter, warning)

@spec add_warning(t(), term() | [term()]) :: t()

Adds a warning to the warnings list. Warnings will not prevent writing, but will be displayed to the user.

apply_and_fetch_dependencies(igniter, opts \\ [])

Applies the current changes to the mix.exs in the Igniter and fetches dependencies.

Returns the remaining changes in the Igniter if successful.

Options

  • :error_on_abort? - If true, raises an error if the user aborts the operation. Returns the original igniter if not.
  • :yes - If true, automatically applies the changes without prompting the user.

assign(igniter, key_vals)

assign(igniter, key, value)

@spec assign(t(), atom(), term()) :: t()

Stores the key/value pair in igniter.assigns

changed?(igniter)

@spec changed?(t() | Rewrite.Source.t()) :: boolean()

Returns true if the igniter or source provided has changed

changed?(igniter, paths)

@spec changed?(t(), String.t() | [String.t()]) :: boolean()

Returns true if any of the files specified in paths have changed.

compose_task(igniter, task, argv \\ nil, fallback \\ nil)

@spec compose_task(
  t(),
  task :: String.t() | module(),
  argv :: [String.t()] | nil,
  fallback :: (t() -> t()) | (t(), [String.t()] -> t()) | nil
) :: t()

Finds the Igniter.Mix.Task task by name and composes it with igniter.

If the task doesn't exist, a fallback function may be provided. This function should accept and return the igniter.

Argument handling

This function calls the task's igniter/1 (or igniter/2) callback, setting igniter.args using the current igniter.args.argv_flags. This prevents composed tasks from accidentally consuming positional arguments. If you wish the composed task to access additional arguments, you must explicitly pass an argv list.

Additionally, you must declare other tasks you are composing with in your task's Igniter.Mix.Task.Info struct using the :composes key. Without this, you'll see unexpected argument errors if a flag that a composed task uses is passed without you explicitly declaring it in your :schema.

Example

def info(_argv, _parent) do
  %Igniter.Mix.Task.Info{
    ...,
    composes: [
      "other.task1",
      "other.task2"
    ]
  }

def igniter(igniter) do
  igniter
  # other.task1 will see igniter.args.argv_flags as its args
  |> Igniter.compose_task("other.task1")
  # other.task2 will see an additional arg and flag
  |> Igniter.compose_task("other.task2", ["arg", "--flag"] ++ igniter.argv.argv_flags)
end

copy_template(igniter, source, target, assigns, opts \\ [])

@spec copy_template(
  igniter :: t(),
  source :: Path.t(),
  target :: Path.t(),
  assigns :: Keyword.t(),
  opts :: Keyword.t()
) :: t()

Copies an EEx template file from the source path to the target path.

Accepts the same options as create_new_file/4.

create_new_elixir_file(igniter, path, contents \\ "", opts \\ [])

This function is deprecated. Use `create_new_file/4`.

create_new_file(igniter, path, contents \\ "", opts \\ [])

Creates a new file in the project with the provided string contents. Adds an error if it already exists.

Options

  • :on_exists - The action to take if the file already exists. Can be
    • :error (default) - Adds an error that prevents any eventual write.
    • :warning - Warns when writing but continues (without overwriting)
    • :skip - Skips writing the file without a warning
    • :overwrite - Warns when writing and overwrites the content with the new content

create_or_update_elixir_file(igniter, path, contents, updater)

@spec create_or_update_elixir_file(t(), Path.t(), String.t(), zipper_updater()) :: t()

Creates the given file in the project with the provided string contents, or updates it with a function of type zipper_updater() if it already exists.

create_or_update_file(igniter, path, contents, updater)

Creates the given file in the project with the provided string contents, or updates it with a function as in update_file/3 (or with zipper_updater() for elixir files) if it already exists.

do_or_dry_run(igniter, opts \\ [])

Executes or dry-runs a given Igniter.

exists?(igniter, path)

@spec exists?(t(), Path.t()) :: boolean()

Checks if a file exists on the file system or in the igniter.

has_changes?(igniter, paths \\ nil)

Returns whether the current Igniter has pending changes.

include_all_elixir_files(igniter)

This function stores in the igniter if its been run before, so it is only run once, which is expensive.

include_existing_elixir_file(igniter, path, opts \\ [])

This function is deprecated. Use `include_existing_file/3` instead.
@spec include_existing_elixir_file(t(), Path.t(), opts :: Keyword.t()) :: t()

include_existing_file(igniter, path, opts \\ [])

@spec include_existing_file(t(), Path.t(), opts :: Keyword.t()) :: t()

Includes the given file in the project, expecting it to exist. Does nothing if its already been added.

include_glob(igniter, glob)

@spec include_glob(t(), Path.t() | GlobEx.t()) :: t()

Includes all files matching the given glob, expecting them all (for now) to be elixir files.

include_or_create_elixir_file(igniter, path, contents \\ "")

This function is deprecated. Use `include_or_create_file/3` instead.
@spec include_or_create_elixir_file(t(), Path.t(), contents :: String.t()) :: t()

include_or_create_file(igniter, path, contents \\ "")

@spec include_or_create_file(t(), Path.t(), contents :: String.t()) :: t()

Includes or creates the given file in the project with the provided contents. Does nothing if its already been added.

install(igniter, package, argv \\ [], opts \\ [])

Installs a package as if calling mix igniter.install

See mix igniter.install for information on the package format.

Options

  • append? - If true, appends the package to the existing list of packages instead of prepending. Defaults to false.

Examples

Igniter.install(igniter, "ash")

Igniter.install(igniter, "ash_authentication@2.0", ["--authentication-strategies", "password,magic_link"])

mkdir(igniter, path)

@spec mkdir(t(), Path.t()) :: t()

Creates a folder in the project.

move_file(igniter, from, from, opts \\ [])

new()

@spec new() :: t()

Returns a new igniter

update_all_elixir_files(igniter, updater)

Runs an update over all elixir files

update_assign(igniter, key, default, fun)

update_elixir_file(igniter, path, func)

@spec update_elixir_file(t(), Path.t(), zipper_updater()) :: t()

Updates the source code of the given elixir file

update_file(igniter, path, updater, opts \\ [])

Updates a given file's Rewrite.Source

update_glob(igniter, glob, func)

@spec update_glob(
  t(),
  Path.t() | GlobEx.t(),
  zipper_updater()
) :: t()

Updates all files matching the given glob with the given zipper function.

Adds any new files matching that glob to the igniter first.