Skip to content

Commit

Permalink
Allow --repo option & --migration-dir for phx.gen.schema (#4905)
Browse files Browse the repository at this point in the history
* Allow --repo option for phx.gen.schema

* Add tests for the repo and migration-dir options in schema generator

The `repo` and `migration-dir` options change the location of the
migrations directory, either to the specified directory or one that
matches the repo name (underscored).

The default is explicitly set to "repo" if neither option is set, to
ensure backwards compatability even if the repo has a different name
than the typical `MyApp.Repo`.

---------

Co-authored-by: Gary Rennie <gazler@gmail.com>
  • Loading branch information
MikaAK and Gazler committed Oct 4, 2023
1 parent e6d0678 commit 09c6bc4
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 6 deletions.
48 changes: 42 additions & 6 deletions lib/mix/tasks/phx.gen.schema.ex
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,21 @@ defmodule Mix.Tasks.Phx.Gen.Schema do
Generated migration can use `binary_id` for schema's primary key
and its references with option `--binary-id`.
## repo
Generated migration can use `repo` to set the migration repository
folder with option `--repo`:
$ mix phx.gen.schema Blog.Post posts --repo MyApp.Repo.Auth
## migration_dir
Generated migrations can be added to a specific `--migration-dir` which sets
the migration folder path:
$ mix phx.gen.schema Blog.Post posts --migration-dir /path/to/directory
## prefix
By default migrations and schemas are generated without a prefix.
Expand Down Expand Up @@ -130,8 +145,8 @@ defmodule Mix.Tasks.Phx.Gen.Schema do

alias Mix.Phoenix.Schema

@switches [migration: :boolean, binary_id: :boolean, table: :string,
web: :string, context_app: :string, prefix: :string]
@switches [migration: :boolean, binary_id: :boolean, table: :string, web: :string,
context_app: :string, prefix: :string, repo: :string, migration_dir: :string]

@doc false
def run(args) do
Expand Down Expand Up @@ -164,10 +179,17 @@ defmodule Mix.Tasks.Phx.Gen.Schema do
parent_opts
|> Keyword.merge(schema_opts)
|> put_context_app(schema_opts[:context_app])
|> maybe_update_repo_module()

schema = Schema.new(schema_name, plural, attrs, opts)
Schema.new(schema_name, plural, attrs, opts)
end

schema
defp maybe_update_repo_module(opts) do
if is_nil(opts[:repo]) do
opts
else
Keyword.update!(opts, :repo, &Module.concat([&1]))
end
end

defp put_context_app(opts, nil), do: opts
Expand All @@ -181,12 +203,26 @@ defmodule Mix.Tasks.Phx.Gen.Schema do
end

@doc false
def copy_new_files(%Schema{context_app: ctx_app} = schema, paths, binding) do
def copy_new_files(%Schema{context_app: ctx_app, repo: repo, opts: opts} = schema, paths, binding) do
files = files_to_be_generated(schema)
Mix.Phoenix.copy_from(paths, "priv/templates/phx.gen.schema", binding, files)

if schema.migration? do
migration_path = Mix.Phoenix.context_app_path(ctx_app, "priv/repo/migrations/#{timestamp()}_create_#{schema.table}.exs")
migration_dir =
cond do
migration_dir = opts[:migration_dir] ->
migration_dir

opts[:repo] ->
repo_name = repo |> Module.split() |> List.last() |> Macro.underscore()
Mix.Phoenix.context_app_path(ctx_app, "priv/#{repo_name}/migrations/")

true ->
Mix.Phoenix.context_app_path(ctx_app, "priv/repo/migrations/")
end

migration_path = Path.join(migration_dir, "#{timestamp()}_create_#{schema.table}.exs")

Mix.Phoenix.copy_from paths, "priv/templates/phx.gen.schema", binding, [
{:eex, "migration.exs", migration_path},
]
Expand Down
34 changes: 34 additions & 0 deletions test/mix/tasks/phx.gen.schema_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,40 @@ defmodule Mix.Tasks.Phx.Gen.SchemaTest do
end
end

test "allows a custom repo", config do
in_tmp_project config.test, fn ->
Gen.Schema.run(~w(Blog.Post blog_posts title:string --repo MyApp.CustomRepo))

assert [migration] = Path.wildcard("priv/custom_repo/migrations/*_create_blog_posts.exs")
assert_file migration, fn file ->
assert file =~ "defmodule MyApp.CustomRepo.Migrations.CreateBlogPosts do"
end
end
end

test "allows a custom migration dir", config do
in_tmp_project config.test, fn ->
Gen.Schema.run(~w(Blog.Post blog_posts title:string --migration-dir priv/custom_dir))

assert [migration] = Path.wildcard("priv/custom_dir/*_create_blog_posts.exs")
assert_file migration, fn file ->
assert file =~ "defmodule Phoenix.Repo.Migrations.CreateBlogPosts do"
end
end
end

test "custom migration_dir takes precedence over custom repo name", config do
in_tmp_project config.test, fn ->
Gen.Schema.run(~w(Blog.Post blog_posts title:string \
--repo MyApp.CustomRepo --migration-dir priv/custom_dir))

assert [migration] = Path.wildcard("priv/custom_dir/*_create_blog_posts.exs")
assert_file migration, fn file ->
assert file =~ "defmodule MyApp.CustomRepo.Migrations.CreateBlogPosts do"
end
end
end

test "does not add maps to the required list", config do
in_tmp_project config.test, fn ->
Gen.Schema.run(~w(Blog.Post blog_posts title:string tags:map published_at:naive_datetime))
Expand Down

0 comments on commit 09c6bc4

Please sign in to comment.