zachdaniel
Igniter - A code generation and project patching framework
Igniter
Igniter is a code generation and project patching framework.
For library authors, this is a tool kit for writing smarter generators that can semantically modify existing files, and all sorts of useful tools for doing so.
For end-users, this means mix igniter.install <package>, which will add it to your mix.exs automatically and then run that library’s installer if it has one. Even when libraries don’t have an installer, or use igniter, this behavior makes it useful to keep around.
Installation
Igniter can be added to an existing elixir project by adding it to your dependencies:
{:igniter, "~> 0.1", only: [:dev]}
You can also generate new projects with igniter preinstalled, and run installers in the same command.
mix igniter.new app_name --install ash
To use this command, install the archive:
mix archive.install hex igniter_new
Patterns
Mix tasks built with igniter are both individually callable, and composable. This means that tasks can call eachother, and also end users can create and customize their own generators composing existing tasks.
Installers
Igniter will look for a task called <your_package>.install when the user runs mix igniter.install <your_package>, and will run it after installing and fetching dependencies.
Generators/Patchers
These can be run like any other mix task, or composed together. For example, lets say that you wanted to have your own Ash.Resource generator, that starts with the default mix ash.gen.resource task, but then adds or modifies files:
# in lib/mix/tasks/my_app.gen.resource.ex
defmodule Mix.Tasks.MyApp.Gen.Resource do
use Igniter.Mix.Task
def igniter(igniter, [resource | _] = argv) do
resource = Igniter.Code.Module.parse(resource)
my_special_thing = Module.concat([resource, SpecialThing])
location = Igniter.Code.Module.proper_location(my_special_thing)
igniter
|> Igniter.compose_task("ash.gen.resource", argv)
|> Igniter.create_new_elixir_file(location, """
defmodule #{inspect(my_special_thing)} do
# this is the special thing for #{inspect()}
end
""")
end
end
Most Liked Responses
zachdaniel
Igniter’s first project-wide refactoring tool!
Rename functions everywhere across your project with one command ![]()
This can also be used by library maintainers in their upgrade scripts
to automatically move users off of deprecated functions.
mix igniter.refactor.rename_function \
Igniter.Code.List.list \
Igniter.Code.List.is_a_list \
--deprecate hard
Speaking of upgrade scripts…
We just released
mix igniter.upgrade ![]()
This command is a drop in replacement for mix deps.update,
except it hooks into any upgrade scripts provided by libraries
that use Igniter! We’re still testing it out, but this also ships
with a --git-ci flag and instructions on how to set up dependabot
to run mix igniter.upgrade automatically
. Think Laravel shift
but free, leveraging our already excellent build tool mix!
mix igniter.upgrade ash
It is still early days, and there will be plenty of rough edges
to sand down, but I truly believe that igniter can play a massive
part in improving the DX around building Elixir applications.
Igniter now provides a fit-for-purpose framework for:
- Installers
- Generators
- Refactoring tools
- Custom code patching
- Upgrade scripts
All that is left is for us to spread it into the ecosystem
Even without adoption, it is useful for end-users as it is today
Happy hacking ![]()
zachdaniel
With mix igniter.install, you can install multiple packages at once! Use the @ symbol to specify specific versions, git/GitHub dependencies, or even path dependencies!
typesend
Kudos to @zachdaniel and everyone else that has been contributing to the Ash Framework. However you feel about adopting Ash itself, so many great libraries keep spinning out of that effort!
(If you haven’t yet, also check out Spark.)









