Mix build utilities, helpers for writing build tasks with Mix
Find a file
2017-08-28 20:46:34 +03:00
config Prevent fs from watching the directory it is started from 2017-06-03 11:41:11 +03:00
lib Switch to file_system for better compatibility 2017-08-28 20:46:34 +03:00
test Rename to MBU and update documentation, make watches wait to trigger 2017-04-03 23:24:52 +03:00
.gitignore Initial commit 2017-03-21 07:44:44 +02:00
CHANGELOG.md Switch to file_system for better compatibility 2017-08-28 20:46:34 +03:00
LICENSE Initial commit 2017-03-21 07:44:44 +02:00
mix.exs Switch to file_system for better compatibility 2017-08-28 20:46:34 +03:00
mix.lock Switch to file_system for better compatibility 2017-08-28 20:46:34 +03:00
README.md Switch to file_system for better compatibility 2017-08-28 20:46:34 +03:00

MBU: Mix Build Utilities

Hex.pm: hex.pm/packages/mbu

Hexdocs: hexdocs.pm/mbu

MBU is a collection of utility functions and scripts to turn Mix into a build tool like Make. Sort of. With it, you can write tasks that build parts of your system, be it front end or back end, without having to leave the safety of Elixir.

Shortly put, MBU allows you to write Mix tasks that depend on other tasks and contains helper functions and macros to make writing them easier. See the basic usage section for code examples.

Basic Usage

A typical MBU task looks like this:

defmodule Mix.Task.Build.Css do
  use MBU.BuildTask
  import MBU.TaskUtils

  @deps [
    "build.scss",
    "build.assets"
  ]

  task _args do
    exec("css-processor", ["--output", "dist/css"]) |> listen()
  end
end

There are a few parts to note here:

  • With MBU, you don't call use Mix.Task, instead you call use MBU.BuildTask that will insert the task macro and internally call use Mix.Task.
  • You can define dependencies to your task with the @deps list. They are executed in parallel before your task is run. If you need to run a task without running the dependencies, you can use MBU.TaskUtils.run_task/2 and give it the deps: false option.
  • The task is enclosed in the task macro that handles running the dependencies and logging debug output. This is compared to the run/1 function of an ordinary Mix task.
  • You can execute programs easily with the MBU.TaskUtils.exec/2 function that is in the MBU.TaskUtils module. It starts the program and returns a program spec that can be given to MBU.TaskUtils.listen/2. The listen function listens to output from the program and prints it on the screen.

MBU also has watch support both for watches builtin to commands and custom watches:

defmodule Mix.Task.Watch.Css do
  use MBU.BuildTask
  import MBU.TaskUtils

  @deps [
    "build.css"
  ]

  task _args do
    [
      # Builtin watch
      exec("css-processor", ["--output", "dist-css", "-w"]),

      # Custom watch
      watch("CopyAssets", "/path/to/assets", fn _events -> File.cp_r!("from", "to") end)
    ]
    |> listen(watch: true)
  end
end

As you can see, there are two types of watches here. The css-processor command has its own watch, activated with a command line flag -w. The second watch is a custom watch, useful for when CLI tools don't have watch support or when you want to run custom Elixir code. The MBU.TaskUtils.watch/3 function takes in the watch name (for logging), directory to watch and a callback function that is called for change events.

Here, the listening function is given an argument watch: true. The arguments makes it listen to the user's keyboard input and if the user presses the enter key, the watches and programs are stopped. Otherwise you would have to kill the task to stop them.

Installation

If available in Hex, the package can be installed by adding mbu to your list of dependencies in mix.exs:

def deps do
  [{:mbu, "~> 2.0.0"}]
end

Documentation can be generated with ExDoc and published on HexDocs. Once published, the docs can be found at https://hexdocs.pm/mbu.