Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Format codebase and add support for multi-tenancy .. #7

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
Binary file added glific_phil_columns-3.1.0.tar
Binary file not shown.
49 changes: 26 additions & 23 deletions lib/mix/phil_columns.ex
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@
defmodule Mix.PhilColumns do

import Mix.EctoSQL

@doc """
Ensures the given repository's seeds path exists on the file system.
"""
@spec ensure_seeds_path(Ecto.Repo.t, Keyword.t) :: String.t
@spec ensure_seeds_path(Ecto.Repo.t(), Keyword.t()) :: String.t()
def ensure_seeds_path(repo, opts) do
path = opts[:seeds_path] || Path.join(source_repo_priv(repo), "seeds")

if not Mix.Project.umbrella? and not File.dir?(path) do
if not Mix.Project.umbrella?() and not File.dir?(path) do
raise_missing_seeds(Path.relative_to_cwd(path), repo)
end

path
end

defp raise_missing_seeds(path, repo) do
Mix.raise """
Could not find seeds directory #{inspect path}
for repo #{inspect repo}.
Mix.raise("""
Could not find seeds directory #{inspect(path)}
for repo #{inspect(repo)}.

This may be because you are in a new project and the
migration directory has not been created yet. Creating an
Expand All @@ -28,57 +27,61 @@ defmodule Mix.PhilColumns do
If you expected existing seeds to be found, please
make sure your repository has been properly configured
and the configured path exists.
"""
""")
end

@doc """
Restarts the app if there was any migration command.
"""
@spec restart_apps_if_migrated([atom], list()) :: :ok
def restart_apps_if_migrated(_apps, []), do: :ok
def restart_apps_if_migrated(apps, [_|_]) do

def restart_apps_if_migrated(apps, [_ | _]) do
# Silence the logger to avoid application down messages.
Logger.remove_backend(:console)

for app <- Enum.reverse(apps) do
Application.stop(app)
end

for app <- apps do
Application.ensure_all_started(app)
end

:ok
after
Logger.add_backend(:console, flush: true)
end

def root_mod(repo_mod) do
name = repo_mod
|> root_mod_name
name =
repo_mod
|> root_mod_name

Module.concat([name])
end

def root_mod_name(repo_mod) do
repo_mod
|> Module.split
|> List.first
|> Module.split()
|> List.first()
end

#@doc """
#Gets a path relative to the application path.
#Raises on umbrella application.
#"""
#def no_umbrella!(task) do
#if Mix.Project.umbrella? do
#Mix.raise "cannot run task #{inspect task} from umbrella application"
#end
#end
# @doc """
# Gets a path relative to the application path.
# Raises on umbrella application.
# """
# def no_umbrella!(task) do
# if Mix.Project.umbrella? do
# Mix.raise "cannot run task #{inspect task} from umbrella application"
# end
# end

@doc """
Gets the seeds path from a repository.
"""
@spec seeds_path(Ecto.Repo.t) :: String.t
@spec seeds_path(Ecto.Repo.t()) :: String.t()
def seeds_path(repo) do
Path.join(source_repo_priv(repo), "seeds")
end

end
33 changes: 20 additions & 13 deletions lib/mix/tasks/phil_columns.gen.seed.ex
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
defmodule Mix.Tasks.PhilColumns.Gen.Seed do

use Mix.Task

import Mix.Ecto
Expand All @@ -12,31 +11,40 @@ defmodule Mix.Tasks.PhilColumns.Gen.Seed do
no_umbrella!("phil_columns.gen.seed")
repos = parse_repo(args)

Enum.each repos, fn repo ->
Enum.each(repos, fn repo ->
case OptionParser.parse(args) do
{_, [name], _} ->
ensure_repo(repo, args)
path = Path.relative_to(seeds_path(repo), Mix.Project.app_path)
path = Path.relative_to(seeds_path(repo), Mix.Project.app_path())
file = Path.join(path, "#{timestamp()}_#{name}.exs")
create_directory path
create_file file, seed_template(root_mod: root_mod(repo),
mod: Module.concat([repo, Seeds, Inflex.camelize(name)]))
create_directory(path)

create_file(
file,
seed_template(
root_mod: root_mod(repo),
mod: Module.concat([repo, Seeds, Inflex.camelize(name)])
)
)

{_, _, _} ->
Mix.raise "expected phil_columns.gen.seed to receive the seed file name, " <>
"got: #{inspect Enum.join(args, " ")}"
Mix.raise(
"expected phil_columns.gen.seed to receive the seed file name, " <>
"got: #{inspect(Enum.join(args, " "))}"
)
end
end
end)
end

defp timestamp do
{{y, m, d}, {hh, mm, ss}} = :calendar.universal_time()
"#{y}#{pad(m)}#{pad(d)}#{pad(hh)}#{pad(mm)}#{pad(ss)}"
end

defp pad(i) when i < 10, do: << ?0, ?0 + i >>
defp pad(i) when i < 10, do: <<?0, ?0 + i>>
defp pad(i), do: to_string(i)

embed_template :seed, """
embed_template(:seed, """
defmodule <%= inspect @mod %> do
use <%= inspect @root_mod %>.Seed

Expand All @@ -45,6 +53,5 @@ defmodule Mix.Tasks.PhilColumns.Gen.Seed do
def up(_repo) do
end
end
"""

""")
end
36 changes: 26 additions & 10 deletions lib/mix/tasks/phil_columns.rollback.ex
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
defmodule Mix.Tasks.PhilColumns.Rollback do

use Mix.Task

import Mix.Ecto
Expand All @@ -8,13 +7,23 @@ defmodule Mix.Tasks.PhilColumns.Rollback do
@shortdoc "Executes the seeds for specified env and tags down"

def run(args, seeder \\ &PhilColumns.Seeder.run/4) do
repos = parse_repo(args)
|> List.wrap()
repos =
parse_repo(args)
|> List.wrap()

{opts, _, _} = OptionParser.parse args,
switches: [all: :boolean, step: :integer, to: :integer, quiet: :boolean,
pool_size: :integer, env: :string],
aliases: [e: :env, n: :steps, v: :to]
{opts, _, _} =
OptionParser.parse(args,
switches: [
all: :boolean,
step: :integer,
to: :integer,
quiet: :boolean,
pool_size: :integer,
env: :string,
tenant: :string
],
aliases: [e: :env, n: :steps, v: :to]
)

opts =
if opts[:to] || opts[:step] || opts[:all],
Expand All @@ -36,6 +45,11 @@ defmodule Mix.Tasks.PhilColumns.Rollback do
do: Keyword.put(opts, :env, String.to_atom(opts[:env])),
else: Keyword.put(opts, :env, :dev)

opts =
if opts[:tenant],
do: opts,
else: Keyword.put(opts, :tenant, "main")

# Start ecto_sql explicitly before as we don't need
# to restart those apps if migrated.
{:ok, _} = Application.ensure_all_started(:ecto_sql)
Expand All @@ -54,10 +68,12 @@ defmodule Mix.Tasks.PhilColumns.Rollback do
end

case PhilColumns.Seeder.with_repo(repo, fun, [mode: :temporary] ++ opts) do
{:ok, migrated, apps} -> restart_apps_if_migrated(apps, migrated)
{:error, error} -> Mix.raise "Could not start repo #{inspect repo}, error: #{inspect error}"
{:ok, migrated, apps} ->
restart_apps_if_migrated(apps, migrated)

{:error, error} ->
Mix.raise("Could not start repo #{inspect(repo)}, error: #{inspect(error)}")
end
end
end

end
52 changes: 40 additions & 12 deletions lib/mix/tasks/phil_columns.seed.ex
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
defmodule Mix.Tasks.PhilColumns.Seed do

use Mix.Task

import Mix.Ecto
Expand All @@ -8,13 +7,27 @@ defmodule Mix.Tasks.PhilColumns.Seed do
@shortdoc "Executes the seeds for specified env and tags up"

def run(args, seeder \\ &PhilColumns.Seeder.run/4) do
repos = parse_repo(args)
|> List.wrap()

{opts, _, _} = OptionParser.parse args,
switches: [all: :boolean, step: :integer, to: :integer, quiet: :boolean,
pool_size: :integer, env: :string, tags: :string],
aliases: [e: :env, n: :step, t: :tags, v: :to]
# This will start our application
Mix.Task.run("app.start")

repos =
parse_repo(args)
|> List.wrap()

{opts, _, _} =
OptionParser.parse(args,
switches: [
all: :boolean,
step: :integer,
to: :integer,
quiet: :boolean,
pool_size: :integer,
env: :string,
tags: :string,
tenant: :string
],
aliases: [e: :env, n: :step, t: :tags, v: :to]
)

opts =
if opts[:to] || opts[:step] || opts[:all],
Expand All @@ -38,9 +51,22 @@ defmodule Mix.Tasks.PhilColumns.Seed do

opts =
if opts[:tags],
do: Keyword.put(opts, :tags, String.split(opts[:tags], ",") |> List.wrap |> Enum.map(fn(tag) -> String.to_atom(tag) end) |> Enum.sort),
do:
Keyword.put(
opts,
:tags,
String.split(opts[:tags], ",")
|> List.wrap()
|> Enum.map(fn tag -> String.to_atom(tag) end)
|> Enum.sort()
),
else: Keyword.put(opts, :tags, [])

opts =
if opts[:tenant],
do: opts,
else: Keyword.put(opts, :tenant, "main")

# Start ecto_sql explicitly before as we don't need
# to restart those apps if migrated.
{:ok, _} = Application.ensure_all_started(:ecto_sql)
Expand All @@ -59,10 +85,12 @@ defmodule Mix.Tasks.PhilColumns.Seed do
end

case PhilColumns.Seeder.with_repo(repo, fun, [mode: :temporary] ++ opts) do
{:ok, migrated, apps} -> restart_apps_if_migrated(apps, migrated)
{:error, error} -> Mix.raise "Could not start repo #{inspect repo}, error: #{inspect error}"
{:ok, migrated, apps} ->
restart_apps_if_migrated(apps, migrated)

{:error, error} ->
Mix.raise("Could not start repo #{inspect(repo)}, error: #{inspect(error)}")
end
end
end

end
34 changes: 24 additions & 10 deletions lib/mix/tasks/phil_columns.seeds.ex
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
defmodule Mix.Tasks.PhilColumns.Seeds do

use Mix.Task

import Mix.Ecto
Expand Down Expand Up @@ -27,12 +26,15 @@ defmodule Mix.Tasks.PhilColumns.Seeds do

@doc false
def run(args, seeds \\ &PhilColumns.Seeder.seeds/3, puts \\ &IO.puts/1) do
repos = parse_repo(args)
|> List.wrap()
repos =
parse_repo(args)
|> List.wrap()

{opts, _, _} = OptionParser.parse args,
switches: [env: :string, tags: :string],
aliases: [e: :env, t: :tags]
{opts, _, _} =
OptionParser.parse(args,
switches: [env: :string, tags: :string, tenant: :string],
aliases: [e: :env, t: :tags]
)

opts =
if opts[:env],
Expand All @@ -41,14 +43,27 @@ defmodule Mix.Tasks.PhilColumns.Seeds do

opts =
if opts[:tags],
do: Keyword.put(opts, :tags, String.split(opts[:tags], ",") |> List.wrap |> Enum.map(fn(tag) -> String.to_atom(tag) end) |> Enum.sort),
do:
Keyword.put(
opts,
:tags,
String.split(opts[:tags], ",")
|> List.wrap()
|> Enum.map(fn tag -> String.to_atom(tag) end)
|> Enum.sort()
),
else: Keyword.put(opts, :tags, [])

opts =
if opts[:tenant],
do: opts,
else: Keyword.put(opts, :tenant, "main")

for repo <- repos do
ensure_repo(repo, args)
path = ensure_seeds_path(repo, opts)

case PhilColumns.Seeder.with_repo(repo, &seeds.(&1, path, opts), [mode: :temporary]) do
case PhilColumns.Seeder.with_repo(repo, &seeds.(&1, path, opts), mode: :temporary) do
{:ok, repo_status, _} ->
puts.(
"""
Expand All @@ -64,7 +79,7 @@ defmodule Mix.Tasks.PhilColumns.Seeds do
)

{:error, error} ->
Mix.raise "Could not start repo #{inspect repo}, error: #{inspect error}"
Mix.raise("Could not start repo #{inspect(repo)}, error: #{inspect(error)}")
end
end
end
Expand All @@ -74,5 +89,4 @@ defmodule Mix.Tasks.PhilColumns.Seeds do
|> to_string()
|> String.pad_trailing(pad)
end

end
Loading