zf

zenflows testing
git clone https://s.sonu.ch/~srfsh/zf.git
Log | Files | Refs | Submodules | README | LICENSE

ecto.gen.migration.ex (3818B)


      1 defmodule Mix.Tasks.Ecto.Gen.Migration do
      2   use Mix.Task
      3 
      4   import Macro, only: [camelize: 1, underscore: 1]
      5   import Mix.Generator
      6   import Mix.Ecto
      7   import Mix.EctoSQL
      8 
      9   @shortdoc "Generates a new migration for the repo"
     10 
     11   @aliases [
     12     r: :repo
     13   ]
     14 
     15   @switches [
     16     change: :string,
     17     repo: [:string, :keep],
     18     no_compile: :boolean,
     19     no_deps_check: :boolean,
     20     migrations_path: :string
     21   ]
     22 
     23   @moduledoc """
     24   Generates a migration.
     25 
     26   The repository must be set under `:ecto_repos` in the
     27   current app configuration or given via the `-r` option.
     28 
     29   ## Examples
     30 
     31       $ mix ecto.gen.migration add_posts_table
     32       $ mix ecto.gen.migration add_posts_table -r Custom.Repo
     33 
     34   The generated migration filename will be prefixed with the current
     35   timestamp in UTC which is used for versioning and ordering.
     36 
     37   By default, the migration will be generated to the
     38   "priv/YOUR_REPO/migrations" directory of the current application
     39   but it can be configured to be any subdirectory of `priv` by
     40   specifying the `:priv` key under the repository configuration.
     41 
     42   This generator will automatically open the generated file if
     43   you have `ECTO_EDITOR` set in your environment variable.
     44 
     45   ## Command line options
     46 
     47     * `-r`, `--repo` - the repo to generate migration for
     48     * `--no-compile` - does not compile applications before running
     49     * `--no-deps-check` - does not check dependencies before running
     50     * `--migrations-path` - the path to run the migrations from, defaults to `priv/repo/migrations`
     51 
     52   ## Configuration
     53 
     54   If the current app configuration specifies a custom migration module
     55   the generated migration code will use that rather than the default
     56   `Ecto.Migration`:
     57 
     58       config :ecto_sql, migration_module: MyApplication.CustomMigrationModule
     59 
     60   """
     61 
     62   @impl true
     63   def run(args) do
     64     repos = parse_repo(args)
     65 
     66     Enum.map repos, fn repo ->
     67       case OptionParser.parse!(args, strict: @switches, aliases: @aliases) do
     68         {opts, [name]} ->
     69           ensure_repo(repo, args)
     70           path = opts[:migrations_path] || Path.join(source_repo_priv(repo), "migrations")
     71           base_name = "#{underscore(name)}.exs"
     72           file = Path.join(path, "#{timestamp()}_#{base_name}")
     73           unless File.dir?(path), do: create_directory path
     74 
     75           fuzzy_path = Path.join(path, "*_#{base_name}")
     76           if Path.wildcard(fuzzy_path) != [] do
     77             Mix.raise "migration can't be created, there is already a migration file with name #{name}."
     78           end
     79 
     80           # The :change option may be used by other tasks but not the CLI
     81           assigns = [mod: Module.concat([repo, Migrations, camelize(name)]), change: opts[:change]]
     82           create_file file, migration_template(assigns)
     83 
     84           if open?(file) and Mix.shell().yes?("Do you want to run this migration?") do
     85             Mix.Task.run "ecto.migrate", ["-r", inspect(repo), "--migrations-path", path]
     86           end
     87 
     88           file
     89 
     90         {_, _} ->
     91           Mix.raise "expected ecto.gen.migration to receive the migration file name, " <>
     92                     "got: #{inspect Enum.join(args, " ")}"
     93       end
     94     end
     95   end
     96 
     97   defp timestamp do
     98     {{y, m, d}, {hh, mm, ss}} = :calendar.universal_time()
     99     "#{y}#{pad(m)}#{pad(d)}#{pad(hh)}#{pad(mm)}#{pad(ss)}"
    100   end
    101 
    102   defp pad(i) when i < 10, do: <<?0, ?0 + i>>
    103   defp pad(i), do: to_string(i)
    104 
    105   defp migration_module do
    106     case Application.get_env(:ecto_sql, :migration_module, Ecto.Migration) do
    107       migration_module when is_atom(migration_module) -> migration_module
    108       other -> Mix.raise "Expected :migration_module to be a module, got: #{inspect(other)}"
    109     end
    110   end
    111 
    112   embed_template :migration, """
    113   defmodule <%= inspect @mod %> do
    114     use <%= inspect migration_module() %>
    115 
    116     def change do
    117   <%= @change %>
    118     end
    119   end
    120   """
    121 end