defmodule Mix.Tasks.Monorepo.Export do
@moduledoc """
Takes all the dependenceis of the project and exports as a .ez files.
$ mix monorepo.export
The export is always done for a combination of lockfile, arch, erlang/elixir
vsns such that for every update in dependencies, versions or similar the
archives must be rexported
Only dependencies from hex are exported.
"""
@shortdoc "Export all dependencies as archives."
use Mix.Task
@impl true
def run(_args) do
env = Mix.env()
Mix.Task.run(:compile, [])
if dist = Mix.Project.config()[:monodist] do
dist = Path.expand(dist)
dir = Path.join([dist, "#{Mix.env()}", target()])
existing = Path.wildcard(Path.join([dist, "#{Mix.env()}", "**"]))
deps = Mix.Dep.load_on_environment(only: env)
lock = Mix.Dep.Lock.read()
# Output the archives
new =
for %{app: app, status: status} <- deps do
# Assume hex SCM manager
{:ok, vsn} = status
case lock[app] do
nil ->
# don't export archive not managed by hex
nil
lock ->
{^app, ^vsn, chksum} = lock_meta(app, lock)
output = Path.join([dir, "#{app}-#{vsn}-#{chksum}.ez"])
input = Path.join([Mix.Project.build_path(), "lib", "#{app}"])
# Only export if not already present
if not File.exists?(output) do
Mix.Task.rerun("archive.build", ["-i", input, "-o", output])
end
output
end
end
stale = existing -- [dir | new]
# Remove old distribution files
for old <- stale do
IO.write(:stderr, "remove stale archive #{old}")
File.rm_rf!(old)
end
end
:ok
end
@doc """
Get the source checksum of from a lock
"""
def lock_meta(app, {:hex, app, vsn, _checksum, _mngr, _deps, _repo, chksum}),
do: {app, vsn, String.slice(chksum, 0, 7)}
def lock_meta(app, {:git, _remote, ref, _opts}), do: {app, ref, ref}
# {:git, "https://github.com/lafka/elixir-keycloak.git", "650500fbd72b55847be3d81deb4b66ceafa99770", [ref: "650500fbd72b55847be3d81deb4b66ceafa99770"]}
def lock_meta(app, nil), do: {app, nil, "0000000"}
@doc """
Get runtime target
"""
def target() do
arch = :erlang.system_info(:system_architecture)
elixir_vsn = System.version()
erlang_vsn = System.otp_release()
Enum.join([arch, erlang_vsn, elixir_vsn], "-")
end
end