Packages
exrm
0.14.5
1.0.8
1.0.6
1.0.5
1.0.4
1.0.3
1.0.2
1.0.1
1.0.0
1.0.0-rc8
1.0.0-rc7
1.0.0-rc6
1.0.0-rc5
1.0.0-rc4
1.0.0-rc3
0.19.9
0.19.8
0.19.7
0.19.6
0.19.5
0.19.4
0.19.3
0.19.2
0.19.1
0.19.0
0.18.8
0.18.7
0.18.6
0.18.5
0.18.4
0.18.3
0.18.2
0.18.1
0.18.0
0.17.3
0.17.2
0.17.1
0.17.0
0.16.0
0.15.3
0.15.2
0.15.1
0.15.0
0.14.17
0.14.16
0.14.15
0.14.14
0.14.13
0.14.12
0.14.11
0.14.10
0.14.9
0.14.8
0.14.7
0.14.6
0.14.5
0.14.3
0.14.2
0.14.1
0.14.0
0.12.12
0.12.11
0.12.10
0.12.9
0.12.8
0.12.7
0.12.6
0.12.5
0.12.4
0.11.3
0.11.2
0.11.1
0.11.0
0.10.3
0.10.1
0.10.0
0.9.2
0.9.1
0.8.1
0.8.0
0.7.3
0.7.2
0.7.1
0.7.0
0.6.15
0.6.14
0.6.13
0.6.12
0.6.11
0.6.10
0.6.9
0.6.8
0.6.7
0.6.6
0.6.5
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.0
0.4.7
Exrm, or Elixir Release Manager, provides mix tasks for building, upgrading, and controlling release packages for your application.
Current section
Files
Jump to
Current section
Files
lib/exrm/plugin.ex
defmodule ReleaseManager.Plugin do
@moduledoc """
This module provide a simple way to add additional steps to
the release task.
You can define your own plugins using the sample definition below. Note that
the module namespace must be nested under `ReleaseManager.Plugin.*`.
defmodule ReleaseManager.Plugin.Hello do
use ReleaseManager.Plugin
def before_release(%Config{} = config) do
info "This is executed just prior to compiling the release"
end
def after_release(%Config{} = config) do
info "This is executed just after compiling the release"
end
def after_cleanup(_args) do
info "This is executed just after running cleanup"
end
end
A couple things are imported or aliased for you. Those things are:
- The ReleaseManager.Config struct is aliased for you to just Config
- `debug/1`, `info/1`, `warn/1`, `notice/1`, and `error/1` are imported for you.
These should be used to do any output for the user.
`before_release/1` and `after_release/1` are required callbacks, and will each be passed a
`Config` struct, containing the configuration for the release task. You can choose
to return the config struct modified or unmodified, or not at all. In the former case,
any modifications you made will be passed on to the remaining plugins and the final
release task. The required callback `after_cleanup/1` is passed the command line arguments.
The return value is not used.
All plugins are executed just prior, and just after compiling the release, as the name of
the callbacks reflect. The `before_release/1` callback is called after some internal tasks,
such as generating the sys.config and others.
"""
use Behaviour
@doc """
A plugin needs to implement `before_release/1`, and `after_release/1`
both of which receive a %ReleaseManager.Config struct
"""
defcallback before_release(ReleaseManager.Config.t) :: any
defcallback after_release(ReleaseManager.Config.t) :: any
@doc false
defmacro __using__(_opts) do
quote do
@behaviour ReleaseManager.Plugin
alias ReleaseManager.Config
import ReleaseManager.Utils, only: [debug: 1, info: 1, warn: 1, notice: 1, error: 1]
Module.register_attribute __MODULE__, :name, accumulate: false, persist: true
Module.register_attribute __MODULE__, :moduledoc, accumulate: false, persist: true
Module.register_attribute __MODULE__, :shortdoc, accumulate: false, persist: true
end
end
@doc """
Loads all plugins in all code paths.
"""
@spec load_all() :: [] | [atom]
def load_all, do: load_plugins(:code.get_path)
@doc """
Loads all plugins in the given `paths`.
"""
@spec load_plugins([binary]) :: [] | [atom]
def load_plugins(paths) do
Enum.reduce(paths, [], fn(path, matches) ->
{:ok, files} = :erl_prim_loader.list_dir(path)
Enum.reduce(files, matches, &match_plugins/2)
end)
end
@re_pattern Regex.re_pattern(~r/Elixir\.ReleaseManager\.Plugin\..*\.beam$/)
@spec match_plugins(char_list, [atom]) :: [atom]
defp match_plugins(filename, modules) do
if :re.run(filename, @re_pattern, [capture: :none]) == :match do
mod = :filename.rootname(filename, '.beam') |> List.to_atom
if Code.ensure_loaded?(mod), do: [mod | modules], else: modules
else
modules
end
end
end