Current section

Files

Jump to
singyeong_plugin lib mix tasks singyeong package.ex
Raw

lib/mix/tasks/singyeong/package.ex

defmodule Mix.Tasks.Singyeong.Package do
use Mix.Task
require Logger
@shortdoc "Packages up a plugin from your compiled code + natives."
def run(_) do
Mix.Task.run "compile"
project =
Mix.Project.config()[:app]
|> Atom.to_string
cwd = File.cwd!()
work_dir = "#{cwd}/work"
beam_dir = "#{work_dir}/beam"
natives_dir = "#{work_dir}/natives"
out = "#{cwd}/#{project}.zip"
if File.exists?(work_dir) do
Logger.info "Cleaning up working directory #{work_dir}..."
File.rm_rf! work_dir
end
if File.exists?(out) do
Logger.info "Cleaning up plugin output #{out}..."
end
File.mkdir_p! beam_dir
File.mkdir_p! natives_dir
{plugin_code, native_code} = scan_files project, File.exists?("_build/prod")
# Copy code into workdir
plugin_code
|> Enum.each(fn file ->
file_name =
file
|> String.split("/")
|> Enum.reverse
|> hd
File.copy! file, "#{beam_dir}/#{file_name}"
end)
native_code
|> Enum.each(fn file ->
file_name =
file
|> String.split("/")
|> Enum.reverse
|> hd
File.copy! file, "#{natives_dir}/#{file_name}"
end)
# Zip it up
zipped_files =
work_dir
|> File.ls!
|> Enum.map(&to_charlist/1)
_res = create_zip out, zipped_files, work_dir
Logger.info "Created plugin zip #{out}."
end
defp scan_files(project_name, prod) do
base_path =
if prod do
"_build/prod/lib"
else
# No point in copying test BEAM files
"_build/dev/lib"
end
dependencies =
base_path
|> File.ls!
|> Enum.filter(fn dir -> dir != project_name end)
|> Enum.map(fn dir ->
File.ls! "#{base_path}/#{dir}/ebin"
end)
|> List.flatten
|> MapSet.new
plugin_dependency_code =
base_path
|> File.ls!
|> Enum.filter(fn dir -> dir == project_name end)
|> Enum.flat_map(fn dir ->
"#{base_path}/#{dir}/consolidated"
|> File.ls!
|> Enum.map(fn file ->
"#{base_path}/#{dir}/consolidated/#{file}"
end)
end)
|> Enum.filter(fn beam_file ->
file_name =
beam_file
|> String.split("/")
|> Enum.reverse
|> hd
MapSet.member? dependencies, file_name
end)
plugin_code =
base_path
|> File.ls!
|> Enum.filter(fn dir -> dir == project_name end)
|> Enum.map(fn dir ->
files = File.ls! "#{base_path}/#{dir}/ebin"
{dir, files}
end)
|> Enum.flat_map(fn {dir, files} ->
Enum.map files, fn file -> "#{base_path}/#{dir}/ebin/#{file}" end
end)
plugin_native_code =
base_path
|> File.ls!
|> Enum.filter(fn dir -> dir == project_name end)
|> Enum.filter(fn dir -> File.exists?("#{base_path}/#{dir}/priv/native") end)
|> Enum.map(fn dir ->
files = File.ls! "#{base_path}/#{dir}/priv/native"
{dir, files}
end)
|> Enum.flat_map(fn {dir, files} ->
Enum.map files, fn file -> "#{base_path}/#{dir}/priv/native/#{file}" end
end)
{plugin_code ++ plugin_dependency_code, plugin_native_code}
end
defp create_zip(zip_name, files, cwd) do
files = Enum.map files, &to_charlist/1
:zip.create zip_name, files, cwd: cwd
end
end