defmodule Mix.Tasks.Rivet.Commit do use Mix.Task import Mix.Ecto import Rivet.Mix.Common # "Manage Rivet migrations" @shortdoc "Commit pending Rivet Model Migrations" @moduledoc @shortdoc @switches [ # all: :boolean, # step: :integer, # to: :integer, # to_exclusive: :integer, quiet: :boolean, prefix: :string, pool_size: :integer, log_sql: :boolean, log_migrations_sql: :boolean, log_migrator_sql: :boolean, strict_version_order: :boolean, repo: [:keep, :string], no_compile: :boolean, no_deps_check: :boolean # migrations_path: :keep ] @defaults [ all: true, log: false, log_migrations_sql: false, log_migrator_sql: false ] @doc """ Notes/Options: 1. call at the top level Mix.Tasks.Ecto.Migrate.run(), with a different Migrator as the second argument: https://github.com/elixir-ecto/ecto_sql/blob/v3.9.2/lib/mix/tasks/ecto.migrate.ex#L111 2. clone the run command above and adjust it to suite (taking this option for now) """ @impl true # a clone of https://github.com/elixir-ecto/ecto_sql/blob/v3.9.2/lib/mix/tasks/ecto.migrate.ex#L111 def run(args) do migrator = &Ecto.Migrator.run/4 # brittle for now {:ok, cfg, _, migs} = get_migrations(args) IO.inspect(cfg) repos = parse_repo(args) {opts, _} = OptionParser.parse!(args, strict: @switches, aliases: []) opts = Keyword.merge(@defaults, opts) {:ok, _} = Application.ensure_all_started(:ecto_sql) for repo <- repos do ensure_repo(repo, args) pool = repo.config[:pool] fun = if Code.ensure_loaded?(pool) and function_exported?(pool, :unboxed_run, 2) do &pool.unboxed_run(&1, fn -> migrator.(&1, migs, :up, opts) end) else &migrator.(&1, migs, :up, opts) end case Ecto.Migrator.with_repo(repo, fun, [mode: :temporary] ++ opts) do {:ok, _migrated, _apps} -> :ok {:error, error} -> Mix.raise("Could not start repo #{inspect(repo)}, error: #{inspect(error)}") end end :ok end defp get_migrations(opts) do with {:ok, cfg, opts} <- option_configs(opts), {:ok, migs} <- Rivet.Mix.Migration.migrations(cfg, opts) do {:ok, cfg, opts, Enum.map(migs, fn %{module: mod, index: ver, path: path} -> Code.require_file(path) if Code.ensure_loaded?(mod) and function_exported?(mod, :__migration__, 0) do {ver, mod} else raise Ecto.MigrationError, "Module #{mod} in #{path} does not define an Ecto.Migration" end end)} end end end