From 0a0c6627218b632f2c86ee8da4d7b998f85c5a8b Mon Sep 17 00:00:00 2001 From: Chris Laskey Date: Fri, 23 Apr 2021 12:21:19 -0400 Subject: [PATCH] Enhance mix task artemis.gen.resource --- apps/artemis/lib/mix/task_helpers/files.ex | 14 ++++ apps/artemis/lib/mix/task_helpers/prompts.ex | 17 ++-- .../lib/mix/tasks/artemis.gen.resource.ex | 79 ++++++++++++++++--- 3 files changed, 96 insertions(+), 14 deletions(-) diff --git a/apps/artemis/lib/mix/task_helpers/files.ex b/apps/artemis/lib/mix/task_helpers/files.ex index 86bd0525..964fedf9 100644 --- a/apps/artemis/lib/mix/task_helpers/files.ex +++ b/apps/artemis/lib/mix/task_helpers/files.ex @@ -1,6 +1,10 @@ defmodule Mix.TaskHelpers.Files do import Mix.TaskHelpers.Commands + defmodule AssertError do + defexception message: "Context Error" + end + @moduledoc """ Functions for managing files and file contents. @@ -9,6 +13,16 @@ defmodule Mix.TaskHelpers.Files do [loki](https://github.com/khusnetdinov/loki) """ + @doc """ + Assert the given path exists + """ + def assert_path_exists(path) do + case execute("test -r #{path} && echo success") do + "success" -> true + _ -> raise(AssertError, "The required path `#{path}` not found") + end + end + @doc """ Copy files and directories """ diff --git a/apps/artemis/lib/mix/task_helpers/prompts.ex b/apps/artemis/lib/mix/task_helpers/prompts.ex index caca2c7d..773689e5 100644 --- a/apps/artemis/lib/mix/task_helpers/prompts.ex +++ b/apps/artemis/lib/mix/task_helpers/prompts.ex @@ -80,17 +80,24 @@ defmodule Mix.TaskHelpers.Prompts do end @doc """ - Print value to shell with error code and red ANSI color output + Print an error """ - def error(value, code \\ 1) + def error_message(message) do + print([red("Error: "), message]) + end + + @doc """ + Print value to shell and exit with error code and red ANSI color output + """ + def error_message_and_exit(value, code \\ 1) - def error(value, code) when is_map(value) do + def error_message_and_exit(value, code) when is_map(value) do value |> inspect() - |> error(code) + |> error_message_and_exit(code) end - def error(value, code) do + def error_message_and_exit(value, code) do Mix.shell().error(value) exit({:shutdown, code}) diff --git a/apps/artemis/lib/mix/tasks/artemis.gen.resource.ex b/apps/artemis/lib/mix/tasks/artemis.gen.resource.ex index 4b4690a3..15711483 100644 --- a/apps/artemis/lib/mix/tasks/artemis.gen.resource.ex +++ b/apps/artemis/lib/mix/tasks/artemis.gen.resource.ex @@ -7,6 +7,8 @@ defmodule Mix.Tasks.Artemis.Gen.Resource do import Mix.TaskHelpers.Prompts import Mix.TaskHelpers.Strings + alias Mix.TaskHelpers.Files.AssertError + @app_web "artemis_web" @apps [ @@ -379,11 +381,13 @@ defmodule Mix.Tasks.Artemis.Gen.Resource do """) end - defp execute_step("Schema", config) do + defp execute_step("Schema" = step, config) do root_directory = "apps/#{config.app}/lib/#{config.app}/schemas" source_directory = "#{root_directory}/#{config.cases.source.single.snakecase_lower}.ex" target_directory = "#{root_directory}/#{config.cases.target.single.snakecase_lower}.ex" + assert_path_exists(source_directory) + copy("#{source_directory}", "#{target_directory}") execute_with_all_cases(config, fn source, target -> @@ -398,6 +402,8 @@ defmodule Mix.Tasks.Artemis.Gen.Resource do Open the schema file `#{target_directory}` and replace fields with the correct values. """) + rescue + error in AssertError -> execute_step_error(error.message, step, config) end defp execute_step("Test Factory", config) do @@ -418,11 +424,13 @@ defmodule Mix.Tasks.Artemis.Gen.Resource do """) end - defp execute_step("Schema Tests", config) do + defp execute_step("Schema Tests" = step, config) do root_directory = "apps/#{config.app}/test/#{config.app}/schemas" source_directory = "#{root_directory}/#{config.cases.source.single.snakecase_lower}_test.exs" target_directory = "#{root_directory}/#{config.cases.target.single.snakecase_lower}_test.exs" + assert_path_exists(source_directory) + copy("#{source_directory}", "#{target_directory}") execute_with_all_cases(config, fn source, target -> @@ -442,13 +450,17 @@ defmodule Mix.Tasks.Artemis.Gen.Resource do $ cd apps/#{config.app} $ mix test test/#{config.app}/schemas/#{config.cases.target.single.snakecase_lower}_test.exs """) + rescue + error in AssertError -> execute_step_error(error.message, step, config) end - defp execute_step("Contexts", config) do + defp execute_step("Contexts" = step, config) do root_directory = "apps/#{config.app}/lib/#{config.app}/contexts" source_directory = "#{root_directory}/#{config.cases.source.single.snakecase_lower}" target_directory = "#{root_directory}/#{config.cases.target.single.snakecase_lower}" + assert_path_exists(source_directory) + copy("#{source_directory}", "#{target_directory}") rename(target_directory, config.cases.source.plural.snakecase_lower, config.cases.target.plural.snakecase_lower) @@ -457,13 +469,17 @@ defmodule Mix.Tasks.Artemis.Gen.Resource do execute_with_all_cases(config, fn source, target -> replace("#{target_directory}", source, target) end) + rescue + error in AssertError -> execute_step_error(error.message, step, config) end - defp execute_step("Context Tests", config) do + defp execute_step("Context Tests" = step, config) do root_directory = "apps/#{config.app}/test/#{config.app}/contexts" source_directory = "#{root_directory}/#{config.cases.source.single.snakecase_lower}" target_directory = "#{root_directory}/#{config.cases.target.single.snakecase_lower}" + assert_path_exists(source_directory) + copy("#{source_directory}", "#{target_directory}") rename(target_directory, config.cases.source.plural.snakecase_lower, config.cases.target.plural.snakecase_lower) @@ -486,6 +502,8 @@ defmodule Mix.Tasks.Artemis.Gen.Resource do $ cd apps/#{config.app} $ mix test test/#{config.app}/contexts/#{config.cases.target.single.snakecase_lower} """) + rescue + error in AssertError -> execute_step_error(error.message, step, config) end defp execute_step("Permissions", config) do @@ -573,35 +591,45 @@ defmodule Mix.Tasks.Artemis.Gen.Resource do """) end - defp execute_step("Controller", config) do + defp execute_step("Controller" = step, config) do root_directory = "apps/#{config.app_web}/lib/#{config.app_web}/controllers" source_directory = "#{root_directory}/#{config.cases.source.single.snakecase_lower}_controller.ex" target_directory = "#{root_directory}/#{config.cases.target.single.snakecase_lower}_controller.ex" + assert_path_exists(source_directory) + copy("#{source_directory}", "#{target_directory}") execute_with_all_cases(config, fn source, target -> replace("#{target_directory}", source, target) end) + rescue + error in AssertError -> execute_step_error(error.message, step, config) end - defp execute_step("View", config) do + defp execute_step("View" = step, config) do root_directory = "apps/#{config.app_web}/lib/#{config.app_web}/views" source_directory = "#{root_directory}/#{config.cases.source.single.snakecase_lower}_view.ex" target_directory = "#{root_directory}/#{config.cases.target.single.snakecase_lower}_view.ex" + assert_path_exists(source_directory) + copy("#{source_directory}", "#{target_directory}") execute_with_all_cases(config, fn source, target -> replace("#{target_directory}", source, target) end) + rescue + error in AssertError -> execute_step_error(error.message, step, config) end - defp execute_step("Templates", config) do + defp execute_step("Templates" = step, config) do root_directory = "apps/#{config.app_web}/lib/#{config.app_web}/templates" source_directory = "#{root_directory}/#{config.cases.source.single.snakecase_lower}" target_directory = "#{root_directory}/#{config.cases.target.single.snakecase_lower}" + assert_path_exists(source_directory) + copy("#{source_directory}/", "#{target_directory}/") rename(target_directory, config.cases.source.plural.snakecase_lower, config.cases.target.plural.snakecase_lower) @@ -610,13 +638,17 @@ defmodule Mix.Tasks.Artemis.Gen.Resource do execute_with_all_cases(config, fn source, target -> replace("#{target_directory}/*", source, target) end) + rescue + error in AssertError -> execute_step_error(error.message, step, config) end - defp execute_step("Controller Tests", config) do + defp execute_step("Controller Tests" = step, config) do root_directory = "apps/#{config.app_web}/test/#{config.app_web}/controllers" source_directory = "#{root_directory}/#{config.cases.source.single.snakecase_lower}_controller_test.exs" target_directory = "#{root_directory}/#{config.cases.target.single.snakecase_lower}_controller_test.exs" + assert_path_exists(source_directory) + copy("#{source_directory}", "#{target_directory}") rename(target_directory, config.cases.source.plural.snakecase_lower, config.cases.target.plural.snakecase_lower) @@ -640,13 +672,17 @@ defmodule Mix.Tasks.Artemis.Gen.Resource do $ cd apps/#{config.app_web} $ mix test test/#{config.app_web}/controllers/#{config.cases.target.single.snakecase_lower}_controller_test.exs" """) + rescue + error in AssertError -> execute_step_error(error.message, step, config) end - defp execute_step("Browser Tests", config) do + defp execute_step("Browser Tests" = step, config) do root_directory = "apps/#{config.app_web}/test/#{config.app_web}/browser" source_directory = "#{root_directory}/#{config.cases.source.single.snakecase_lower}_page_test.exs" target_directory = "#{root_directory}/#{config.cases.target.single.snakecase_lower}_page_test.exs" + assert_path_exists(source_directory) + copy("#{source_directory}", "#{target_directory}") execute_with_all_cases(config, fn source, target -> @@ -666,6 +702,8 @@ defmodule Mix.Tasks.Artemis.Gen.Resource do $ cd apps/#{config.app_web} $ mix test --include browser test/#{config.app_web}/browser/#{config.cases.target.single.snakecase_lower}_page_test.exs" """) + rescue + error in AssertError -> execute_step_error(error.message, step, config) end defp execute_step("Navigation", config) do @@ -704,4 +742,27 @@ defmodule Mix.Tasks.Artemis.Gen.Resource do defp execute_step(step, _config) do print("#{step} step is not implemented yet") end + + defp execute_step_error(message, step, config) do + error_message(message) + line_break() + + print("Either manually resolve the error then repeat the step, ignore the error, or exit.") + line_break() + + response = + "Repeat step #{step}?" + |> choose(["repeat", "ignore", "exit"], default: "repeat") + |> Kernel.||("") + |> lowercase() + + repeat? = Enum.member?(["r", "repeat", ""], response) + ignore? = Enum.member?(["i", "ignore"], response) + + cond do + repeat? -> execute_step(step, config) + ignore? -> true + true -> exit_task(0) + end + end end