Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Igniter task to install Phoenix #140

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 49 additions & 35 deletions lib/igniter.ex
Original file line number Diff line number Diff line change
Expand Up @@ -1129,48 +1129,62 @@ defmodule Igniter do
source -> source
end

if Rewrite.Source.from?(source, :string) do
content_lines =
source
|> Rewrite.Source.get(:content)
|> String.split("\n")
|> Enum.with_index()

space_padding =
content_lines
|> Enum.map(&elem(&1, 1))
|> Enum.max()
|> to_string()
|> String.length()

diffish_looking_text =
Enum.map_join(content_lines, "\n", fn {line, line_number_minus_one} ->
line_number = line_number_minus_one + 1

"#{String.pad_trailing(to_string(line_number), space_padding)} #{color(IO.ANSI.yellow(), color?)}| #{color(IO.ANSI.green(), color?)}#{line}#{color(IO.ANSI.reset(), color?)}"
end)
cond do
Rewrite.Source.from?(source, :string) &&
String.valid?(Rewrite.Source.get(source, :content)) ->
content_lines =
source
|> Rewrite.Source.get(:content)
|> String.split("\n")
|> Enum.with_index()

space_padding =
content_lines
|> Enum.map(&elem(&1, 1))
|> Enum.max()
|> to_string()
|> String.length()

diffish_looking_text =
Enum.map_join(content_lines, "\n", fn {line, line_number_minus_one} ->
line_number = line_number_minus_one + 1

"#{String.pad_trailing(to_string(line_number), space_padding)} #{color(IO.ANSI.yellow(), color?)}| #{color(IO.ANSI.green(), color?)}#{line}#{color(IO.ANSI.reset(), color?)}"
end)

if String.trim(diffish_looking_text) != "" do
"""
Create: #{Rewrite.Source.get(source, :path)}
if String.trim(diffish_looking_text) != "" do
"""
Create: #{Rewrite.Source.get(source, :path)}

#{diffish_looking_text}
"""
else
""
end
else
diff = Rewrite.Source.diff(source, color: color?) |> IO.iodata_to_binary()
#{diffish_looking_text}
"""
else
""
end

String.valid?(Rewrite.Source.get(source, :content)) ->
diff = Rewrite.Source.diff(source, color: color?) |> IO.iodata_to_binary()

if String.trim(diff) != "" do
"""
Update: #{Rewrite.Source.get(source, :path)}

if String.trim(diff) != "" do
#{diff}
"""
else
""
end

!String.valid?(Rewrite.Source.get(source, :content)) ->
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some files do not have a valid string content, for eg binary files like favicon.ico but I think we still need to display that such file will be created. Might need to improve this code to detect updates as well.

"""
Update: #{Rewrite.Source.get(source, :path)}
Create: #{Rewrite.Source.get(source, :path)}

#{diff}
(content diff can't be displayed)
"""
else

:else ->
dbg(source)
""
end
end
end)
end
Expand Down
116 changes: 116 additions & 0 deletions lib/igniter/phoenix/generator.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
defmodule Igniter.Phoenix.Generator do
@moduledoc false
# Wrap Phx.New.Generator
# https://github.com/phoenixframework/phoenix/blob/7586cbee9e37afbe0b3cdbd560b9e6aa60d32bf6/installer/lib/phx_new/generator.ex#L69

def copy_from(igniter, project, mod, name) when is_atom(name) do
mapping = mod.template_files(name)

templates =
for {format, _project_location, files} <- mapping,
{source, target_path} <- files,
source = to_string(source) do
target = expand_path_with_bindings(target_path, project)
{format, source, target}
end

Enum.reduce(templates, igniter, fn {format, source, target}, acc ->
case format do
:keep ->
acc

:text ->
contents = mod.render(name, source, project.binding)
Igniter.create_new_file(acc, target, contents, on_exists: :overwrite)
leandrocp marked this conversation as resolved.
Show resolved Hide resolved

:config ->
contents = mod.render(name, source, project.binding)
config_inject(acc, target, contents)

:prod_config ->
contents = mod.render(name, source, project.binding)
prod_only_config_inject(acc, target, contents)

:eex ->
contents = mod.render(name, source, project.binding)
Igniter.create_new_file(acc, target, contents, on_exists: :overwrite)
end
end)
end

defp expand_path_with_bindings(path, project) do
Regex.replace(Regex.recompile!(~r/:[a-zA-Z0-9_]+/), path, fn ":" <> key, _ ->
project |> Map.fetch!(:"#{key}") |> to_string()
end)
end

defp config_inject(igniter, file, to_inject) do
patterns = [
"""
import Config
__cursor__()
"""
]

Igniter.create_or_update_elixir_file(igniter, file, to_inject, fn zipper ->
case Igniter.Code.Common.move_to_cursor_match_in_scope(zipper, patterns) do
{:ok, zipper} ->
{:ok, Igniter.Code.Common.add_code(zipper, to_inject)}

_ ->
{:warning,
"""
Could not automatically inject the following config into #{file}

#{to_inject}
"""}
end
end)
end

defp prod_only_config_inject(igniter, file, to_inject) do
patterns = [
"""
if config_env() == :prod do
__cursor__()
end
""",
"""
if :prod == config_env() do
__cursor__()
end
"""
]

Igniter.create_or_update_elixir_file(igniter, file, to_inject, fn zipper ->
case Igniter.Code.Common.move_to_cursor_match_in_scope(zipper, patterns) do
{:ok, zipper} ->
{:ok, Igniter.Code.Common.add_code(zipper, to_inject)}

_ ->
{:warning,
"""
Could not automatically inject the following config into #{file}

#{to_inject}
"""}
end
end)
end

def gen_ecto_config(igniter, %{binding: binding}) do
adapter_config = binding[:adapter_config]

config_inject(igniter, "config/dev.exs", """
# Configure your database
config :#{binding[:app_name]}, #{binding[:app_module]}.Repo#{kw_to_config(adapter_config[:dev])}
""")
end

defp kw_to_config(kw) do
Enum.map(kw, fn
{k, {:literal, v}} -> ",\n #{k}: #{v}"
{k, v} -> ",\n #{k}: #{inspect(v)}"
end)
end
end
71 changes: 71 additions & 0 deletions lib/igniter/phoenix/single.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
defmodule Igniter.Phoenix.Single do
@moduledoc false
# Wrap Phx.New.Single
# https://github.com/phoenixframework/phoenix/blob/7586cbee9e37afbe0b3cdbd560b9e6aa60d32bf6/installer/lib/phx_new/single.ex

alias Phx.New.Project
alias Igniter.Phoenix.Generator

@mod Phx.New.Single

def generate(igniter, project) do
generators = [
{true, &gen_new/2},
{Project.ecto?(project), &gen_ecto/2},
{Project.html?(project), &gen_html/2},
{Project.mailer?(project), &gen_mailer/2},
{Project.gettext?(project), &gen_gettext/2},
{true, &gen_assets/2}
]

Enum.reduce(generators, igniter, fn
{true, gen_fun}, acc -> gen_fun.(acc, project)
_, acc -> acc
end)
end

def gen_new(igniter, project) do
Generator.copy_from(igniter, project, @mod, :new)
end

def gen_ecto(igniter, project) do
igniter
|> Generator.copy_from(project, @mod, :ecto)
|> Generator.gen_ecto_config(project)
end

def gen_html(igniter, project) do
Generator.copy_from(igniter, project, @mod, :html)
end

def gen_mailer(igniter, project) do
Generator.copy_from(igniter, project, @mod, :mailer)
end

def gen_gettext(igniter, project) do
Generator.copy_from(igniter, project, @mod, :gettext)
end

def gen_assets(igniter, project) do
javascript? = Project.javascript?(project)
css? = Project.css?(project)
html? = Project.html?(project)

igniter = Generator.copy_from(igniter, project, @mod, :static)

igniter =
if html? or javascript? do
command = if javascript?, do: :js, else: :no_js
Generator.copy_from(igniter, project, @mod, command)
else
igniter
end

if html? or css? do
command = if css?, do: :css, else: :no_css
Generator.copy_from(igniter, project, @mod, command)
else
igniter
end
end
end
1 change: 1 addition & 0 deletions lib/igniter/project/config.ex
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ defmodule Igniter.Project.Config do
end)
end

@doc false
defp ensure_default_configs_exist(igniter, file)
when file in ["config/dev.exs", "config/test.exs", "config/prod.exs"] do
igniter
Expand Down
Loading
Loading