lib/mix/tasks/altworx.scenario_release_internal.ex

defmodule Mix.Tasks.Altworx.ScenarioReleaseInternal do
  use Mix.Task

  @shortdoc "Assembles an Altworx scenario release"

  @moduledoc """
  Assembles an Altworx scenario release for the current project.

      $ MIX_ENV=prod mix altworx.scenario_release_internal

  ## Command line options

    * `--force` - forces recompilation
    * `--no-archives-check` - does not check archive
    * `--no-deps-check` - does not check dependencies
    * `--no-elixir-version-check` - does not check Elixir version
    * `--no-compile` - does not compile before assembling the release
    * `--overwrite` - if there is an existing release version, overwrite it
    * `--path` - the path of the release
    * `--quiet` - does not write progress to the standard output
    * `--version` - the version of the release
  """

  alias Config.Reader
  alias Mix.Project
  alias Mix.ProjectStack
  alias Mix.Release
  alias Mix.Task

  @impl true
  def run(args) do
    Project.get!()
    config = Project.config()
    app = Keyword.fetch!(config, :app)
    :ok = configure_release(app)
    Task.run("release", args)
  end

  defp configure_release(app) do
    :ok = ProjectStack.merge_config(releases: [scenario_release_config(app)])
  end

  defp scenario_release_config(app) do
    {app,
     [
       include_erts: false,
       strip_beams: false,
       steps: [:assemble, &update_sys_config/1, :tar]
     ]}
  end

  defp update_sys_config(%Release{} = release) do
    config = Project.config()

    sys_config =
      if File.regular?(config[:config_path]) do
        config[:config_path] |> Reader.read!(env: Mix.env(), target: Mix.target())
      else
        []
      end

    sys_config = runbox_scenario_app_into_sys_config(sys_config)
    config_provider_path = {:system, "RELEASE_SYS_CONFIG", ".config"}
    :ok = Release.make_sys_config(release, sys_config, config_provider_path)
    release
  end

  defp runbox_scenario_app_into_sys_config(sys_config) do
    config = Project.config()
    app = Keyword.fetch!(config, :app)
    Keyword.put(sys_config, :runbox, scenario_app: app)
  end
end