Packages
igniter
0.1.1
0.8.2
0.8.1
0.8.0
0.7.9
0.7.8
0.7.7
0.7.6
0.7.5
0.7.4
0.7.3
0.7.2
0.7.1
0.7.0
0.6.30
0.6.29
0.6.28
0.6.27
0.6.26
0.6.25
0.6.24
0.6.23
0.6.22
0.6.21
0.6.20
0.6.19
0.6.18
0.6.17
0.6.16
0.6.15
0.6.14
0.6.13
0.6.12
0.6.11
0.6.10
0.6.9
0.6.8
0.6.7
0.6.6
0.6.5
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.52
0.5.51
0.5.50
0.5.49
0.5.48
0.5.47
0.5.46
0.5.45
0.5.44
0.5.43
0.5.42
0.5.41
0.5.40
0.5.39
0.5.38
0.5.37
0.5.36
0.5.35
0.5.34
0.5.33
0.5.32
0.5.31
0.5.30
0.5.29
0.5.28
0.5.27
0.5.26
0.5.25
0.5.24
0.5.23
0.5.22
0.5.21
0.5.20
0.5.19
0.5.18
0.5.17
0.5.16
0.5.15
0.5.14
0.5.13
0.5.12
0.5.11
0.5.10
0.5.9
0.5.8
0.5.7
0.5.6
0.5.5
0.5.4
0.5.3
0.5.2
0.5.1
0.5.0
0.4.8
0.4.7
0.4.6
0.4.5
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.3.78
0.3.77
0.3.76
0.3.75
0.3.74
0.3.73
0.3.72
0.3.71
0.3.70
0.3.69
0.3.68
0.3.67
0.3.66
0.3.65
0.3.64
0.3.63
0.3.62
0.3.61
0.3.60
0.3.59
0.3.58
0.3.57
0.3.56
0.3.55
0.3.54
0.3.53
0.3.52
0.3.51
0.3.50
0.3.49
0.3.48
0.3.47
0.3.46
0.3.45
0.3.44
0.3.43
0.3.42
0.3.41
0.3.40
0.3.39
0.3.38
0.3.37
0.3.36
0.3.35
0.3.34
0.3.33
0.3.32
0.3.31
0.3.30
0.3.29
0.3.28
0.3.27
0.3.26
0.3.25
0.3.24
0.3.23
0.3.22
0.3.21
0.3.20
0.3.19
0.3.18
0.3.17
0.3.16
0.3.15
0.3.14
0.3.13
0.3.12
0.3.11
0.3.10
0.3.9
0.3.8
0.3.7
0.3.6
0.3.5
0.3.4
0.3.3
0.3.2
0.3.1
0.3.0
0.2.13
0.2.12
0.2.11
0.2.10
0.2.9
0.2.8
0.2.7
0.2.6
0.2.5
0.2.4
0.2.3
0.2.2
0.2.1
0.2.0
0.1.8
0.1.7
0.1.6
0.1.5
0.1.4
0.1.3
0.1.2
0.1.1
0.1.0
A code generation and project patching framework
Current section
Files
Jump to
Current section
Files
lib/application.ex
defmodule Igniter.Application do
@moduledoc "Codemods and tools for working with Application modules."
require Igniter.Code.Common
require Igniter.Code.Function
alias Igniter.Code.Common
alias Sourceror.Zipper
@doc "Returns the name of the current application."
@spec app_name() :: atom()
def app_name do
Mix.Project.config()[:app]
end
@doc "Adds a new child to the `children` list in the application file"
@spec add_new_child(Igniter.t(), module() | {module, term()}) :: Igniter.t()
def add_new_child(igniter, to_supervise) do
project = Mix.Project.get!()
to_perform =
case project.application()[:mod] do
nil -> {:create_an_app, Igniter.Code.Module.module_name("Application")}
{mod, _} -> {:modify, mod}
mod -> {:modify, mod}
end
case to_perform do
{:create_an_app, mod} ->
igniter
|> create_app(mod)
|> do_add_child(mod, to_supervise)
{:modify, mod} ->
do_add_child(igniter, mod, to_supervise)
end
end
def create_app(igniter, application) do
igniter
|> point_to_application_in_mix_exs(application)
|> create_application_file(application)
end
def do_add_child(igniter, application, to_supervise) do
path = Igniter.Code.Module.proper_location(application)
diff_checker =
case to_supervise do
v when is_atom(v) ->
&Common.nodes_equal?/2
{v, _opts} when is_atom(v) ->
fn
{item, _}, {right, _} ->
Common.nodes_equal?(item, right)
item, {right, _} ->
Common.nodes_equal?(item, right)
_, _ ->
false
end
end
Igniter.update_elixir_file(igniter, path, fn zipper ->
with {:ok, zipper} <- Igniter.Code.Module.move_to_module_using(zipper, Application),
{:ok, zipper} <- Igniter.Code.Module.move_to_def(zipper, :start, 2) do
zipper
|> Igniter.Code.Function.move_to_function_call_in_current_scope(:=, [2], fn call ->
Igniter.Code.Function.argument_matches_pattern?(
call,
0,
{:children, _, context} when is_atom(context)
) &&
Igniter.Code.Function.argument_matches_pattern?(call, 1, v when is_list(v))
end)
|> case do
{:ok, zipper} ->
zipper
|> Zipper.down()
|> Zipper.rightmost()
|> Igniter.Code.List.append_new_to_list(to_supervise, diff_checker)
_ ->
{:error,
"Expected the `start/2` function in `#{path}` to have a `children = [...]` assignment."}
end
else
_ ->
{:error, "Expected `#{path}` to be an Application with a `start` function"}
end
end)
end
defp create_application_file(igniter, application) do
path = Igniter.Code.Module.proper_location(application)
contents = """
defmodule #{inspect(application)} do
@moduledoc false
use Application
@impl true
def start(_type, _args) do
children = []
opts = [strategy: :one_for_one, name: Foo.Supervisor]
Supervisor.start_link(children, opts)
end
end
"""
Igniter.create_new_elixir_file(igniter, path, contents)
end
defp point_to_application_in_mix_exs(igniter, application) do
Igniter.update_elixir_file(igniter, "mix.exs", fn zipper ->
case Igniter.Code.Module.move_to_module_using(zipper, Mix.Project) do
{:ok, zipper} ->
case Igniter.Code.Module.move_to_def(zipper, :application, 0) do
{:ok, zipper} ->
zipper
|> Zipper.rightmost()
|> Igniter.Code.Keyword.set_keyword_key(:mod, {application, []}, fn z ->
{:ok, Zipper.replace(z, {application, []})}
end)
_ ->
Common.add_code(zipper, """
def application do
[
mod: {#{inspect(application)}, []}
]
end
""")
end
_ ->
{:error, "Required a module using `Mix.Project` to exist in `mix.exs`"}
end
end)
end
end