zachdaniel

zachdaniel

Creator of Ash

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

zachdaniel

zachdaniel

Creator of Ash

Igniter’s first project-wide refactoring tool!

Rename functions everywhere across your project with one command :smiling_face_with_sunglasses:
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 :fire: mix igniter.upgrade :fire:

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 :robot:. 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 :smiling_face_with_sunglasses:

zachdaniel

zachdaniel

Creator of Ash

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

typesend

:clap: 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.)

zachdaniel

zachdaniel

Creator of Ash

We’ve made an update to igniter in 0.4.x that changes slightly how you write tasks.

It is a very small update, but adds a convenience around dealing with options and arguments.

It’s “soft deprecated” for now, it won’t warn, but eventually it will. Essentially, instead of:

def igniter(igniter, argv) do
  {arguments, argv} = positional!(argv)
  options = options!(argv)
end

you can now do

def igniter(igniter) do
  # positional args are in 
  igniter.args.positional
  # options are in 
  igniter.args.options
  # argv without positional args (for composition) are in 
  igniter.args.argv_flags`
  # raw argue are in 
  igniter.args.argv

  ...
end

Additionally, mix igniter.upgrade in 0.3.x had some issues that may make it not work, so manual upgrade to 0.4.x will likely be required. More on that in the readme.

jimsynz

jimsynz

Ash Core Team

I’m so excited to see where this tool goes!

Where Next?

Popular in Libraries Top

oltarasenko
Dear Elixir community, After a year of development, bug fixes, and improvements, we are proudly ready to share the release of Crawly 0.1...
New
markmark206
simple_feature_flags is a tiny package that lets you turn features on or off based on which environment (e.g. localhost, staging, product...
New
KronicDeth
Elixir plugin for JetBrain’s IntelliJ Platform (including Rubymine) This is a plugin that adds support for Elixir to JetBrains IntelliJ...
289 35421 110
New
MRdotB
I needed to reuse React components from my Chrome extension in my Phoenix/LiveView backend. I noticed that for Svelte/Vue, there are live...
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 42633 214
New
vic
Expat is a tiny experiment I did for extracting patterns and being able to reuse them (compose and share patterns between elixir librarie...
New
Azolo
Hey everyone, I just released WebSockex which is a Elixir WebSocket client. WebSockex strives to work as a OTP special process, be RFC6...
New
Hal9000
Here is my first stab at this. README pasted below. https://github.com/Hal9000/elixir_random Comments and critiques are welcome. Th...
New
ostinelli
Let’s write a database! Well not really, but I think it’s a little sad that there doesn’t seem to be a simple in-memory distributed KV da...
New
mplatts
With HEEX released we decided to start a components library using Tailwind CSS - check it out here: Petal Components. We also have a boi...
New

Other popular topics Top

bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
sergio
I couldn’t find any guides that worked well with Phoenix 1.6.0 and esbuild. I hope this helps people test the waters and eases you into t...
New
malloryerik
Hi, this is for people who, like me, have had some friction using .html.heex templates in VSCode. The solution seems to be, in a hyphena...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
script
If I have a string “1000 cfu/ml” . I want to remove the characters and / and space . So the string is like this "1000" What is the ...
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
beno
I will often find my self writing things similar to: case some_value do nil -&gt; something() "" -&gt; something() _ -&gt; someth...
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New

Sub Categories:

We're in Beta

About us Mission Statement