Mix.Config for Mix.install/2

Hi,

New Mix.install/2 in Elixir v1.12 has been very useful for scripting but I have a problem with it.

Is there a way I could implement Mix.Config to define application configuration for the installed dependencies by Mix.install/2 in my single file script?

Since now, on Mix projects I used to follow the /config/config.exs file convention, but now I don’t know how to do it.

Hope someone can help this newbie Elixir developer,

Thanks!

You need to set configuration before starting dependency application … Take a look at my Todo list example:

Mix.install([:ecto_sql, :exqlite])

defmodule Repo do
  use Ecto.Repo, adapter: Ecto.Adapters.Exqlite, otp_app: :my_app
end

defmodule Migration do
  use Ecto.Migration

  def change do
    create table("todo_lists") do
      add(:title, :string)
      timestamps()
    end

    create table("todo_items") do
      add(:description, :string)
      add(:type, :string)
      timestamps()
    end

    # Primary key and timestamps are not required if
    # using many_to_many without schemas
    # create table("todo_list_items", primary_key: false) do
    create table("todo_list_items") do
      add(:todo_item_id, references(:todo_items))
      add(:todo_list_id, references(:todo_lists))
    end
  end
end

defmodule TodoList do
  use Ecto.Schema

  schema "todo_lists" do
    field(:title)
    # has_many(:todo_list_items, TodoListItem)
    # has_many(:todo_items, through: [:todo_list_items, :todo_item])
    # many_to_many(:todo_items, TodoItem, join_through: "todo_list_items")
    many_to_many(:todo_items, TodoItem, join_through: TodoListItem)
    timestamps()
  end
end

defmodule TodoListItem do
  use Ecto.Schema

  schema "todo_list_items" do
    belongs_to(:todo_list, TodoList)
    belongs_to(:todo_item, TodoItem)
    # timestamps()
  end
end

defmodule TodoItem do
  use Ecto.Schema

  schema "todo_items" do
    field(:description, :string)
    field(:type, :string)
    timestamps()
  end
end

defmodule Example do
  alias Ecto.Query
  require Query

  def cleanup do
    Repo.stop()
  end

  def prepare do
    Application.put_env(:my_app, Repo,
      database: "example",
      pool_size: 10,
      show_sensitive_data_on_connection_error: true,
      username: System.get_env("USER")
    )

    Application.ensure_all_started(:ecto_sql)
    Application.ensure_all_started(:postgrex)
    Repo.__adapter__().storage_down(Repo.config())
    Repo.__adapter__().storage_up(Repo.config())
    Repo.start_link()
    Ecto.Migrator.up(Repo, 1, Migration)
  end

  def sample do
    TodoList
    |> Query.from(as: :todo_list)
    |> Query.join(:inner, [todo_list: todo_list], assoc(todo_list, :todo_items), as: :todo_items)
    |> Query.where([todo_items: todo_items], todo_items.type != "hobby")
    |> Query.preload([todo_list: todo_list, todo_items: todo_items], todo_items: todo_items)
    |> Repo.all()
    |> IO.inspect()
  end

  def seed do
    Repo.insert(%TodoList{
      title: "Hobby example",
      todo_items: [%{description: "item1", type: "hobby"}, %{description: "item2", type: "job"}]
    })

    Repo.insert(%TodoList{
      title: "Job example",
      todo_items: [%{description: "item1", type: "job"}, %{description: "item2", type: "job"}]
    })
  end
end

Example.prepare()
Example.seed()
Example.sample()
Example.cleanup()

I guess that it would work same for dependencies as well, but I did not tested how it would work with configuration used at dependency compile-time.

2 Likes

The thread is a bit old but it is worth pointing out some good stuff here:

4 Likes