Search code examples
rakeelixirelixir-mix

Rake like dependency functionality in Elixir Mix tasks?


In Rake, one can specify dependencies between tasks. The engine then build a dependencies tree and perform those tasks by the order of dependencies and only once each task.

Is there a similar mechanism for that in elixir/mix ?

task seed_users: [:seed_companies] do 
  # actions
end

task :seed_companies do
  # actions
end

Solution

  • I don't think there's any inbuilt functionality for this, but you can use Mix.Task.run/2 to achieve this:

    defmodule Mix.Tasks.SeedUsers do
      def run(_args) do
        IO.puts "started seed_users"
        Mix.Task.run "seed_companies"
        Mix.Task.run "seed_companies"
        IO.puts "completed seed_users"
      end
    end
    
    defmodule Mix.Tasks.SeedCompanies do
      def run(_args) do
        IO.puts "started seed_companies"
        IO.puts "completed seed_companies"
      end
    end
    

    Example run:

    $ mix seed_users
    started seed_users
    started seed_companies
    completed seed_companies
    completed seed_users
    

    Note that Mix.Task.run/2 does not run the task if it has already been run once, so if you call Mix.Task.run/2 twice, as in the example above, it's only run once. If you'd like to run a task more than once, you need to call Mix.Task.reenable/1 after every run.