Skip to content

Commit

Permalink
docs: more docs
Browse files Browse the repository at this point in the history
  • Loading branch information
zachdaniel committed Jun 12, 2024
1 parent a156431 commit f1e2336
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 1 deletion.
50 changes: 50 additions & 0 deletions documentation/writing-generators.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Writing Generators

In `Igniter`, generators are done as a wrapper around `Mix.Task`, allowing them to be called individually or composed as part of a task. Since an example is worth a thousand words, lets take a look at an example that generates a file and ensures a configuration is set in the user's `config.exs`.

```elixir
# lib/mix/tasks/your_lib.gen.your_thing.ex
defmodule Mix.Tasks.YourLib.Gen.YourThing do
use Igniter.Mix.Task

def igniter(igniter, [module_name | _ ] = argv) do
module_name = Igniter.Module.parse(module_name)
path = Igniter.Module.proper_location(module_name)
app_name = Igniter.Application.app_name()

igniter
|> Igniter.create_new_elixir_file(igniter, path, """
defmodule #{inspect(module_name)} do
use YourLib.Thing
...some_code
end
""")
|> Igniter.Config.configure(
"config.exs",
app_name,
[:list_of_things],
[module_name],
&Igniter.Code.List.prepend_new_to_list(&1, module_name)
)
end
end
```

Now, your users can run

`mix your_lib.gen.your_thing MyApp.MyModuleName`

and it will present them with a diff, creating a new file and updating their `config.exs`.

Additionally, other generators can "compose" this generator using `Igniter.compose_task/3`

```elixir
igniter
|> Igniter.compose_task(Mix.Tasks.YourLib.Gen.YourThing, ["MyApp.MyModuleName"])
|> Igniter.compose_task(Mix.Tasks.YourLib.Gen.YourThing, ["MyApp.SomeOtherName"])
```

## Writing a library installer

Igniter will look for a mix task called `your_library.install` when a user runs `mix igniter.install your_library`. As long as it has the correct name, it will be run automatically as part of installation!
2 changes: 2 additions & 0 deletions lib/igniter.ex
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ defmodule Igniter do
end

@doc "Finds the `Igniter.Mix.Task` task by name and composes it (calls its `igniter/2`) into the current igniter."
def compose_task(igniter, task, argv \\ [])

def compose_task(igniter, task, argv) when is_atom(task) do
Code.ensure_compiled!(task)

Expand Down
6 changes: 6 additions & 0 deletions lib/mix/task.ex
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
defmodule Igniter.Mix.Task do
@moduledoc "A behaviour for implementing a Mix task that is enriched to be composable with other Igniter tasks."
@doc """
Whether or not it supports being run in the root of an umbrella project
At the moment, this is still experimental and we suggest not turning it on.
"""
@callback supports_umbrella?() :: boolean()
@doc "All the generator behavior happens here, you take an igniter and task arguments, and return an igniter."
@callback igniter(igniter :: Igniter.t(), argv :: list(String.t())) :: Igniter.t()

defmacro __using__(_opts) do
Expand Down
3 changes: 2 additions & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ defmodule Igniter.MixProject do
logo: "logos/igniter-logo-small.png",
extra_section: "GUIDES",
extras: [
{"README.md", title: "Home"}
{"README.md", title: "Home"},
"documentation/writing-generators.md"
# "CHANGELOG.md"
],
before_closing_head_tag: fn type ->
Expand Down

0 comments on commit f1e2336

Please sign in to comment.