defmodule Mix.Tasks.Castle.Relup do
@moduledoc """
Generate a relup file between releases.
`castle.relup` will generate a relup between a `target` release and
any number of other releases. The paths specifed in the options should
be the paths to `.rel` files (but without the .rel extension)
## Command-line options:
- `--target` - the path to the .rel file in the target release
- `--fromto` - the path to the .rel file from a previous release
- `--upfrom` - the path to the .rel file from a previous release
- `--downto` - the path to the .rel file from a previous release
- `--outdir` - the directory to write the relup. Defaults to the current directory
The `--fromto`, `--upfrom` and `--downto` switches may be specified zero or more
times and have the following behaviour:
- `--fromto` generates both upgrade and downgrade instructions
- `--upfrom` generates only upgrade instructions
- `--downto` generates only downgrade instructions
"""
@shortdoc "Generate a relup file between releases"
use Mix.Task
@options [upfrom: :keep, downto: :keep, fromto: :keep, outdir: :string, target: :string]
@impl Mix.Task
def run(command_line_args) do
{:ok, _} = :application.ensure_all_started(:sasl)
case OptionParser.parse(command_line_args, strict: @options) do
{cmdline_args, _, _} ->
relup_args = make_relup_args(cmdline_args)
apply(:systools, :make_relup, relup_args)
end
end
defp make_relup_args(cmdline_args) do
target = Keyword.fetch!(cmdline_args, :target) |> to_charlist()
upfrom = get_rel_paths(cmdline_args, :upfrom)
downto = get_rel_paths(cmdline_args, :downto)
fromto = get_rel_paths(cmdline_args, :fromto)
opts = [path: get_ebin_paths([target] ++ upfrom ++ downto ++ fromto)]
[target, upfrom ++ fromto, downto ++ fromto, opts]
end
defp get_rel_paths(cmdline_args, type) do
cmdline_args
|> Keyword.take([type])
|> Keyword.values()
|> Enum.map(&to_charlist/1)
end
defp get_ebin_paths(relpaths) do
relpaths
|> Enum.map(&Path.join(&1, "../../../lib/*/ebin"))
|> Enum.map(&Path.expand/1)
|> Enum.map(&to_charlist/1)
end
end