diff --git a/lib/igniter/project/deps.ex b/lib/igniter/project/deps.ex index 10ed974..a5ce935 100644 --- a/lib/igniter/project/deps.ex +++ b/lib/igniter/project/deps.ex @@ -68,7 +68,7 @@ defmodule Igniter.Project.Deps do Igniter.add_warning(igniter, error) end - {:ok, current} -> + {:ok, current_source} -> if opts[:on_exists] == :skip do igniter else @@ -82,7 +82,7 @@ defmodule Igniter.Project.Deps do Code.eval_string("{#{inspect(name)}, #{inspect(version)}}") |> elem(0) end - current = Code.eval_string(current) |> elem(0) + current = Code.eval_string(current_source) |> elem(0) {desired, current} = case {desired, current} do @@ -105,12 +105,15 @@ defmodule Igniter.Project.Deps do igniter else + desired_display = dep_declaration_string(name, version, opts[:dep_opts]) + current_display = String.trim(current_source) + if opts[:yes?] || Igniter.Util.IO.yes?(""" Dependency #{name} is already in mix.exs. Should we replace it? - Desired: `#{inspect(desired)}` - Found: `#{inspect(current)}` + Desired: `#{desired_display}` + Found: `#{current_display}` """) do do_add_dependency(igniter, name, version, opts) else @@ -383,6 +386,24 @@ defmodule Igniter.Project.Deps do end end + defp dep_declaration_string(name, version, dep_opts) do + quoted = + if dep_opts do + quote do + {unquote(name), unquote(version), unquote(dep_opts)} + end + else + {:__block__, [], + [ + {{:__block__, [], [name]}, {:__block__, [], [version]}} + ]} + end + + quoted + |> Sourceror.to_string() + |> String.trim() + end + defp do_add_dependency(igniter, name, version, opts) do error_tag = if opts[:error?] do diff --git a/test/igniter/project/deps_test.exs b/test/igniter/project/deps_test.exs index 92d0dbc..3d211a5 100644 --- a/test/igniter/project/deps_test.exs +++ b/test/igniter/project/deps_test.exs @@ -143,6 +143,60 @@ defmodule Igniter.Project.DepsTest do end end + describe "add_dep/3 replace prompt (#338)" do + setup :verify_on_exit! + + test "shows readable quoted runtime in Desired/Found when replacing an existing dep" do + igniter = + test_project( + files: %{ + "mix.exs" => """ + defmodule Test.MixProject do + use Mix.Project + + def project do + [ + app: :test, + version: "0.1.0", + elixir: "~> 1.17", + start_permanent: Mix.env() == :prod, + deps: deps() + ] + end + + def application do + [extra_applications: [:logger]] + end + + defp deps do + [ + {:esbuild, "~> 0.8", runtime: true} + ] + end + end + """ + } + ) + + expect(Igniter.Util.IO, :yes?, fn prompt -> + assert prompt =~ "Desired:" + assert prompt =~ "Found:" + + # https://github.com/ash-project/igniter/issues/338 + assert prompt =~ "Mix.env() == :dev" + refute prompt =~ ":__aliases__" + refute prompt =~ "context:" + + false + end) + + Igniter.Project.Deps.add_dep( + igniter, + {:esbuild, "~> 0.10", runtime: quote(do: Mix.env() == :dev)} + ) + end + end + describe "set_dep_option" do test "sets the option when no options exist" do test_project()