111 lines
2.9 KiB
Elixir
111 lines
2.9 KiB
Elixir
|
defmodule Mix.Tasks.Ecto.Gen.Repo do
|
||
|
use Mix.Task
|
||
|
|
||
|
import Mix.Ecto
|
||
|
import Mix.Generator
|
||
|
|
||
|
@shortdoc "Generates a new repository"
|
||
|
|
||
|
@switches [
|
||
|
repo: [:string, :keep],
|
||
|
]
|
||
|
|
||
|
@aliases [
|
||
|
r: :repo,
|
||
|
]
|
||
|
|
||
|
@moduledoc """
|
||
|
Generates a new repository.
|
||
|
|
||
|
The repository will be placed in the `lib` directory.
|
||
|
|
||
|
## Examples
|
||
|
|
||
|
$ mix ecto.gen.repo -r Custom.Repo
|
||
|
|
||
|
This generator will automatically open the config/config.exs
|
||
|
after generation if you have `ECTO_EDITOR` set in your environment
|
||
|
variable.
|
||
|
|
||
|
## Command line options
|
||
|
|
||
|
* `-r`, `--repo` - the repo to generate
|
||
|
|
||
|
"""
|
||
|
|
||
|
@impl true
|
||
|
def run(args) do
|
||
|
no_umbrella!("ecto.gen.repo")
|
||
|
{opts, _} = OptionParser.parse!(args, strict: @switches, aliases: @aliases)
|
||
|
|
||
|
repo =
|
||
|
case Keyword.get_values(opts, :repo) do
|
||
|
[] -> Mix.raise "ecto.gen.repo expects the repository to be given as -r MyApp.Repo"
|
||
|
[repo] -> Module.concat([repo])
|
||
|
[_ | _] -> Mix.raise "ecto.gen.repo expects a single repository to be given"
|
||
|
end
|
||
|
|
||
|
config = Mix.Project.config()
|
||
|
underscored = Macro.underscore(inspect(repo))
|
||
|
|
||
|
base = Path.basename(underscored)
|
||
|
file = Path.join("lib", underscored) <> ".ex"
|
||
|
app = config[:app] || :YOUR_APP_NAME
|
||
|
opts = [mod: repo, app: app, base: base]
|
||
|
|
||
|
create_directory Path.dirname(file)
|
||
|
create_file file, repo_template(opts)
|
||
|
config_path = config[:config_path] || "config/config.exs"
|
||
|
|
||
|
case File.read(config_path) do
|
||
|
{:ok, contents} ->
|
||
|
check = String.contains?(contents, "import Config")
|
||
|
config_first_line = get_first_config_line(check) <> "\n"
|
||
|
new_contents = config_first_line <> "\n" <> config_template(opts)
|
||
|
Mix.shell().info [:green, "* updating ", :reset, config_path]
|
||
|
File.write! config_path, String.replace(contents, config_first_line, new_contents)
|
||
|
|
||
|
{:error, _} ->
|
||
|
create_file config_path, "import Config\n\n" <> config_template(opts)
|
||
|
end
|
||
|
|
||
|
open?(config_path, 3)
|
||
|
|
||
|
Mix.shell().info """
|
||
|
Don't forget to add your new repo to your supervision tree
|
||
|
(typically in lib/#{app}/application.ex):
|
||
|
|
||
|
def start(_type, _args) do
|
||
|
children = [
|
||
|
#{inspect repo},
|
||
|
]
|
||
|
|
||
|
And to add it to the list of Ecto repositories in your
|
||
|
configuration files (so Ecto tasks work as expected):
|
||
|
|
||
|
config #{inspect app},
|
||
|
ecto_repos: [#{inspect repo}]
|
||
|
|
||
|
"""
|
||
|
end
|
||
|
|
||
|
defp get_first_config_line(true), do: "import Config"
|
||
|
defp get_first_config_line(false), do: "use Mix.Config"
|
||
|
|
||
|
embed_template :repo, """
|
||
|
defmodule <%= inspect @mod %> do
|
||
|
use Ecto.Repo,
|
||
|
otp_app: <%= inspect @app %>,
|
||
|
adapter: Ecto.Adapters.Postgres
|
||
|
end
|
||
|
"""
|
||
|
|
||
|
embed_template :config, """
|
||
|
config <%= inspect @app %>, <%= inspect @mod %>,
|
||
|
database: "<%= @app %>_<%= @base %>",
|
||
|
username: "user",
|
||
|
password: "pass",
|
||
|
hostname: "localhost"
|
||
|
"""
|
||
|
end
|