defmodule Castle do
@moduledoc """
Documentation for `Castle`.
"""
@app Mix.Project.config()[:app]
def make_releases() do
reldir = "releases"
releases_file = Path.join(reldir, "RELEASES")
unless File.exists?(releases_file) do
{:ok, _} = Application.ensure_all_started(:sasl)
[{name, vsn, _, _}] = :release_handler.which_releases(:permanent)
relfile = Path.join([reldir, vsn, "#{name}.rel"])
:ok = :release_handler.create_RELEASES(to_charlist(reldir), relfile, [])
end
end
def generate(vsn) do
rel_vsn_dir = Path.join([:code.root_dir(), "releases", vsn])
# Read the build time config from build.config
{:ok, [build_config]} = :file.consult(to_charlist(Path.join(rel_vsn_dir, "build.config")))
# Generate the sys.config by running the config providers
sys_config =
build_config
|> Keyword.get(@app, [])
|> Keyword.get(:config_providers, [])
|> Enum.reduce(build_config, fn {mod, arg}, cfg -> apply(mod, :load, [cfg, arg]) end)
File.write!(
Path.join(rel_vsn_dir, "sys.config"),
:io_lib.format('%% coding: utf-8~n~tp.~n', [sys_config])
)
end
def unpack(name) when is_binary(name) do
case :release_handler.unpack_release(to_charlist(name)) do
{:ok, vsn} ->
IO.puts("Unpacked #{vsn} ok")
{:error, reason} ->
IO.puts("Failed to unpack #{name}. #{inspect(reason)}")
end
end
def install(vsn) when is_binary(vsn) do
generate(vsn)
case :release_handler.install_release(to_charlist(vsn)) do
{:ok, other_vsn, _} ->
IO.puts("Now running #{vsn} (previously #{other_vsn}).")
{:error, reason} ->
IO.puts("Install of #{vsn} failed. #{inspect(reason)}")
end
end
def commit(vsn) when is_binary(vsn) do
generate(vsn)
case :release_handler.make_permanent(to_charlist(vsn)) do
:ok ->
IO.puts("Committed #{vsn}. System restarts will now boot into this version.")
{:error, reason} ->
IO.puts("Commit of #{vsn} failed. #{inspect(reason)}")
end
end
def remove(vsn) when is_binary(vsn) do
case :release_handler.remove_release(to_charlist(vsn)) do
:ok ->
IO.puts("Removed #{vsn}.")
{:error, reason} ->
IO.puts("Removal of #{vsn} failed. #{inspect(reason)}")
end
end
def releases() do
vsns =
for {_, vsn, _, status} <- :release_handler.which_releases() do
{to_string(vsn), to_string(status)}
end
width =
vsns
|> Enum.map(&elem(&1, 0))
|> Enum.map(&String.length/1)
|> Enum.max()
Enum.each(vsns, fn {vsn, status} ->
IO.puts("#{String.pad_trailing(vsn, width + 2)}#{status}")
end)
end
end