diff --git a/lib/mix/phoenix.ex b/lib/mix/phoenix.ex index 9b901c6c3b..382df2ee5d 100644 --- a/lib/mix/phoenix.ex +++ b/lib/mix/phoenix.ex @@ -206,6 +206,28 @@ defmodule Mix.Phoenix do Path.join(web_prefix(), rel_path) end + @doc """ + Prompts to continue if any files exist. + """ + def prompt_for_conflicts(generator_files) do + file_paths = Enum.map(generator_files, fn {_, _, path} -> path end) + + case Enum.filter(file_paths, &File.exists?(&1)) do + [] -> :ok + conflicts -> + Mix.shell.info""" + The following files conflict with new files to be generated: + + #{conflicts |> Enum.map(&" * #{&1}") |> Enum.join("\n")} + + See the --web option to namespace similarly named resources + """ + unless Mix.shell.yes?("Proceeed with interactive overwrite?") do + System.halt() + end + end + end + defp web_module(base) do if base |> to_string() |> String.ends_with?(".Web") do Module.concat(base, nil) diff --git a/lib/mix/tasks/phx.gen.context.ex b/lib/mix/tasks/phx.gen.context.ex index 7b1933b864..fb3e25b854 100644 --- a/lib/mix/tasks/phx.gen.context.ex +++ b/lib/mix/tasks/phx.gen.context.ex @@ -71,11 +71,19 @@ defmodule Mix.Tasks.Phx.Gen.Context do binding = [context: context, schema: schema] paths = Mix.Phoenix.generator_paths() + prompt_for_conflicts(context) + context |> copy_new_files(paths, binding) |> print_shell_instructions() end + defp prompt_for_conflicts(context) do + context + |> files_to_be_generated() + |> Mix.Phoenix.prompt_for_conflicts() + end + def build(args) do switches = [binary_id: :boolean, table: :string, web: :string] {opts, parsed, _} = OptionParser.parse(args, switches: switches) @@ -91,6 +99,10 @@ defmodule Mix.Tasks.Phx.Gen.Context do {context, schema} end + def files_to_be_generated(%Context{schema: schema}) do + Gen.Schema.files_to_be_generated(schema) + end + def copy_new_files(%Context{schema: schema} = context, paths, binding) do Gen.Schema.copy_new_files(schema, paths, binding) inject_schema_access(context, paths, binding) @@ -100,7 +112,9 @@ defmodule Mix.Tasks.Phx.Gen.Context do end defp inject_schema_access(%Context{file: file} = context, paths, binding) do - unless Context.pre_existing?(context) do + if Context.pre_existing?(context) do + Mix.shell.info([:green, "* injecting ", :reset, Path.relative_to_cwd(file)]) + else Mix.Generator.create_file(file, Mix.Phoenix.eval_from(paths, "priv/templates/phx.gen.context/context.ex", binding)) end @@ -114,7 +128,9 @@ defmodule Mix.Tasks.Phx.Gen.Context do end defp inject_tests(%Context{test_file: test_file} = context, paths, binding) do - unless Context.pre_existing_tests?(context) do + if Context.pre_existing_tests?(context) do + Mix.shell.info([:green, "* injecting ", :reset, Path.relative_to_cwd(test_file)]) + else Mix.Generator.create_file(test_file, Mix.Phoenix.eval_from(paths, "priv/templates/phx.gen.context/context_test.exs", binding)) end diff --git a/lib/mix/tasks/phx.gen.html.ex b/lib/mix/tasks/phx.gen.html.ex index 20b9b265eb..189de4ed14 100644 --- a/lib/mix/tasks/phx.gen.html.ex +++ b/lib/mix/tasks/phx.gen.html.ex @@ -84,17 +84,25 @@ defmodule Mix.Tasks.Phx.Gen.Html do binding = [context: context, schema: schema, inputs: inputs(schema)] paths = Mix.Phoenix.generator_paths() + prompt_for_conflicts(context) + context |> copy_new_files(paths, binding) |> print_shell_instructions() end - def copy_new_files(%Context{schema: schema} = context, paths, binding) do + defp prompt_for_conflicts(context) do + context + |> files_to_be_generated() + |> Kernel.++(Gen.Context.files_to_be_generated(context)) + |> Mix.Phoenix.prompt_for_conflicts() + end + + def files_to_be_generated(%Context{schema: schema}) do web_prefix = Mix.Phoenix.web_prefix() test_prefix = Mix.Phoenix.test_prefix() web_path = to_string(schema.web_path) - - Mix.Phoenix.copy_from paths, "priv/templates/phx.gen.html", "", binding, [ + [ {:eex, "controller.ex", Path.join([web_prefix, "controllers", web_path, "#{schema.singular}_controller.ex"])}, {:eex, "edit.html.eex", Path.join([web_prefix, "templates", web_path, schema.singular, "edit.html.eex"])}, {:eex, "form.html.eex", Path.join([web_prefix, "templates", web_path, schema.singular, "form.html.eex"])}, @@ -104,7 +112,12 @@ defmodule Mix.Tasks.Phx.Gen.Html do {:eex, "view.ex", Path.join([web_prefix, "views", web_path, "#{schema.singular}_view.ex"])}, {:eex, "controller_test.exs", Path.join([test_prefix,"controllers", web_path, "#{schema.singular}_controller_test.exs"])}, ] + end + + def copy_new_files(%Context{} = context, paths, binding) do + files = files_to_be_generated(context) + Mix.Phoenix.copy_from(paths, "priv/templates/phx.gen.html", "", binding, files) Gen.Context.copy_new_files(context, paths, binding) context end diff --git a/lib/mix/tasks/phx.gen.json.ex b/lib/mix/tasks/phx.gen.json.ex index 4fe1246723..2b5bd63d45 100644 --- a/lib/mix/tasks/phx.gen.json.ex +++ b/lib/mix/tasks/phx.gen.json.ex @@ -73,25 +73,39 @@ defmodule Mix.Tasks.Phx.Gen.Json do binding = [context: context, schema: schema] paths = Mix.Phoenix.generator_paths() + prompt_for_conflicts(context) + context |> copy_new_files(paths, binding) |> print_shell_instructions() end - def copy_new_files(%Context{schema: schema} = context, paths, binding) do + defp prompt_for_conflicts(context) do + context + |> files_to_be_generated() + |> Kernel.++(Gen.Context.files_to_be_generated(context)) + |> Mix.Phoenix.prompt_for_conflicts() + end + + def files_to_be_generated(%Context{schema: schema}) do web_prefix = Mix.Phoenix.web_prefix() test_prefix = Mix.Phoenix.test_prefix() web_path = to_string(schema.web_path) - Mix.Phoenix.copy_from paths, "priv/templates/phx.gen.json", "", binding, [ + [ {:eex, "controller.ex", Path.join([web_prefix, "controllers", web_path, "#{schema.singular}_controller.ex"])}, {:eex, "view.ex", Path.join([web_prefix, "views", web_path, "#{schema.singular}_view.ex"])}, {:eex, "controller_test.exs", Path.join([test_prefix, "controllers", web_path, "#{schema.singular}_controller_test.exs"])}, {:new_eex, "changeset_view.ex", Path.join([web_prefix, "views/changeset_view.ex"])}, {:new_eex, "fallback_controller.ex", Path.join([web_prefix, "controllers/fallback_controller.ex"])}, ] + end + def copy_new_files(%Context{} = context, paths, binding) do + files = files_to_be_generated(context) + Mix.Phoenix.copy_from paths, "priv/templates/phx.gen.json", "", binding, files Gen.Context.copy_new_files(context, paths, binding) + context end diff --git a/lib/mix/tasks/phx.gen.schema.ex b/lib/mix/tasks/phx.gen.schema.ex index 101878f9a1..c38c36454a 100644 --- a/lib/mix/tasks/phx.gen.schema.ex +++ b/lib/mix/tasks/phx.gen.schema.ex @@ -91,11 +91,19 @@ defmodule Mix.Tasks.Phx.Gen.Schema do schema = build(args, []) paths = Mix.Phoenix.generator_paths() + prompt_for_conflicts(schema) + schema |> copy_new_files(paths, schema: schema) |> print_shell_instructions() end + defp prompt_for_conflicts(schema) do + schema + |> files_to_be_generated() + |> Mix.Phoenix.prompt_for_conflicts() + end + def build(args, parent_opts, help \\ __MODULE__) do {schema_opts, parsed, _} = OptionParser.parse(args, switches: @switches) [schema_name, plural | attrs] = validate_args!(parsed, help) @@ -107,6 +115,10 @@ defmodule Mix.Tasks.Phx.Gen.Schema do schema end + def files_to_be_generated(%Schema{} = schema) do + [{:eex, "schema.ex", schema.file}] + end + def copy_new_files(%Schema{} = schema, paths, binding) do migration = schema.module @@ -117,9 +129,8 @@ defmodule Mix.Tasks.Phx.Gen.Schema do |> Phoenix.Naming.underscore() |> String.replace("/", "_") - Mix.Phoenix.copy_from paths, "priv/templates/phx.gen.schema", "", binding, [ - {:eex, "schema.ex", schema.file} - ] + files = files_to_be_generated(schema) + Mix.Phoenix.copy_from(paths,"priv/templates/phx.gen.schema", "", binding, files) if schema.migration? do Mix.Phoenix.copy_from paths, "priv/templates/phx.gen.schema", "", binding, [