ecto.gen.repo.ex (2928B)
1 defmodule Mix.Tasks.Ecto.Gen.Repo do 2 use Mix.Task 3 4 import Mix.Ecto 5 import Mix.Generator 6 7 @shortdoc "Generates a new repository" 8 9 @switches [ 10 repo: [:string, :keep], 11 ] 12 13 @aliases [ 14 r: :repo, 15 ] 16 17 @moduledoc """ 18 Generates a new repository. 19 20 The repository will be placed in the `lib` directory. 21 22 ## Examples 23 24 $ mix ecto.gen.repo -r Custom.Repo 25 26 This generator will automatically open the config/config.exs 27 after generation if you have `ECTO_EDITOR` set in your environment 28 variable. 29 30 ## Command line options 31 32 * `-r`, `--repo` - the repo to generate 33 34 """ 35 36 @impl true 37 def run(args) do 38 no_umbrella!("ecto.gen.repo") 39 {opts, _} = OptionParser.parse!(args, strict: @switches, aliases: @aliases) 40 41 repo = 42 case Keyword.get_values(opts, :repo) do 43 [] -> Mix.raise "ecto.gen.repo expects the repository to be given as -r MyApp.Repo" 44 [repo] -> Module.concat([repo]) 45 [_ | _] -> Mix.raise "ecto.gen.repo expects a single repository to be given" 46 end 47 48 config = Mix.Project.config() 49 underscored = Macro.underscore(inspect(repo)) 50 51 base = Path.basename(underscored) 52 file = Path.join("lib", underscored) <> ".ex" 53 app = config[:app] || :YOUR_APP_NAME 54 opts = [mod: repo, app: app, base: base] 55 56 create_directory Path.dirname(file) 57 create_file file, repo_template(opts) 58 config_path = config[:config_path] || "config/config.exs" 59 60 case File.read(config_path) do 61 {:ok, contents} -> 62 check = String.contains?(contents, "import Config") 63 config_first_line = get_first_config_line(check) <> "\n" 64 new_contents = config_first_line <> "\n" <> config_template(opts) 65 Mix.shell().info [:green, "* updating ", :reset, config_path] 66 File.write! config_path, String.replace(contents, config_first_line, new_contents) 67 68 {:error, _} -> 69 create_file config_path, "import Config\n\n" <> config_template(opts) 70 end 71 72 open?(config_path, 3) 73 74 Mix.shell().info """ 75 Don't forget to add your new repo to your supervision tree 76 (typically in lib/#{app}/application.ex): 77 78 def start(_type, _args) do 79 children = [ 80 #{inspect repo}, 81 ] 82 83 And to add it to the list of Ecto repositories in your 84 configuration files (so Ecto tasks work as expected): 85 86 config #{inspect app}, 87 ecto_repos: [#{inspect repo}] 88 89 """ 90 end 91 92 defp get_first_config_line(true), do: "import Config" 93 defp get_first_config_line(false), do: "use Mix.Config" 94 95 embed_template :repo, """ 96 defmodule <%= inspect @mod %> do 97 use Ecto.Repo, 98 otp_app: <%= inspect @app %>, 99 adapter: Ecto.Adapters.Postgres 100 end 101 """ 102 103 embed_template :config, """ 104 config <%= inspect @app %>, <%= inspect @mod %>, 105 database: "<%= @app %>_<%= @base %>", 106 username: "user", 107 password: "pass", 108 hostname: "localhost" 109 """ 110 end