| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182 |
- defmodule Mix.Tasks.Compile.Asn1 do
- use Mix.Task.Compiler
- @recursive true
- @manifest_vsn 1
- @manifest "compile.asn1"
- # TODO: use manifest to track generated files?
- @impl true
- def manifests(), do: [manifest()]
- defp manifest(), do: Path.join(Mix.Project.manifest_path(), @manifest)
- @impl true
- def run(_args) do
- add_to_path_and_cache(:asn1)
- Mix.Project.get!()
- config = Mix.Project.config()
- app_root = File.cwd!()
- asn1_srcs = config[:asn1_srcs] || []
- manifest_data = read_manifest(manifest())
- manifest_modified_time = Mix.Utils.last_modified(manifest())
- Enum.each(asn1_srcs, &compile(&1, app_root, manifest_modified_time))
- write_manifest(manifest(), manifest_data)
- {:noop, []}
- end
- defp compile(src, app_root, manifest_modified_time) do
- %{
- src: src_path,
- compile_opts: compile_opts
- } = src
- src_path =
- app_root
- |> Path.join(src_path)
- |> Path.expand()
- if stale?(src_path, manifest_modified_time) do
- Mix.shell().info("compiling asn1 file: #{src_path}")
- :ok = :asn1ct.compile(to_charlist(src_path), compile_opts)
- else
- Mix.shell().info("file is up to date, not compiling: #{src_path}")
- end
- end
- defp stale?(file, manifest_modified_time) do
- with true <- File.exists?(file),
- false <- Mix.Utils.stale?([file], [manifest_modified_time]) do
- false
- else
- _ -> true
- end
- end
- defp read_manifest(file) do
- try do
- file |> File.read!() |> :erlang.binary_to_term()
- rescue
- _ -> %{}
- else
- {@manifest_vsn, data} when is_map(data) -> data
- _ -> %{}
- end
- end
- defp write_manifest(file, data) do
- Mix.shell().info("writing manifest #{file}")
- File.mkdir_p!(Path.dirname(file))
- File.write!(file, :erlang.term_to_binary({@manifest_vsn, data}))
- end
- def add_to_path_and_cache(lib_name) do
- :code.lib_dir()
- |> Path.join("#{lib_name}-*")
- |> Path.wildcard()
- |> hd()
- |> Path.join("ebin")
- |> to_charlist()
- |> :code.add_path(:cache)
- end
- end
|