Packages
protox
1.7.1
2.0.9
2.0.8
2.0.7
2.0.6
2.0.5
2.0.4
2.0.3
2.0.2
2.0.1
2.0.0
2.0.0-dev
1.7.8
1.7.7
1.7.6
1.7.5
1.7.4
retired
1.7.3
1.7.2
1.7.1
1.7.0
1.6.10
1.6.9
1.6.8
1.6.7
1.6.6
1.6.5
1.6.4
1.6.3
1.6.2
1.6.1
1.6.0
1.5.1
1.5.0
1.4.0
1.3.2
1.3.1
1.3.0
1.2.4
1.2.3
1.2.2
1.2.1
1.2.0
1.1.1
1.1.0
1.0.0
0.25.0
0.24.0
0.23.1
0.23.0
0.22.0
0.21.0
0.20.0
0.19.1
0.19.0
0.18.0
0.17.0
0.16.2
0.16.1
0.16.0
0.15.2
0.15.1
0.15.0
0.14.0
0.13.0
0.12.1
0.12.0
0.11.1
0.11.0
0.10.0
0.9.1
0.9.0
0.8.0
0.7.1
0.7.0
A fast, easy to use and 100% conformant Elixir library for Google Protocol Buffers (aka protobuf)
Current section
Files
Jump to
Current section
Files
lib/protox/protoc.ex
defmodule Protox.Protoc do
@moduledoc false
def run([proto_file], nil) do
do_run([proto_file], ["-I", "#{proto_file |> Path.dirname() |> Path.expand()}"])
end
def run([proto_file], paths) do
do_run([proto_file], paths_to_protoc_args(paths))
end
def run(proto_files, nil) do
do_run(proto_files, ["-I", "#{common_directory_path(proto_files)}"])
end
def run(proto_files, paths) do
do_run(proto_files, paths_to_protoc_args(paths))
end
# -- Private
defp paths_to_protoc_args(paths) do
paths |> Enum.map(&["-I", &1]) |> Enum.concat()
end
defp do_run(proto_files, args) do
outfile_name = "protox_#{random_string()}"
outfile_path = Path.join([Mix.Project.build_path(), outfile_name])
cmd_args = ["--include_imports", "-o", outfile_path] ++ args ++ proto_files
try do
System.cmd("protoc", cmd_args, stderr_to_stdout: true)
catch
:error, :enoent ->
raise "protoc executable is missing. Please make sure Protocol Buffers " <>
"is installed and available system wide"
else
{_, 0} ->
file_content = File.read!(outfile_path)
:ok = File.rm(outfile_path)
{:ok, file_content}
{msg, _} ->
{:error, msg}
end
end
defp common_directory_path(paths_rel) do
paths = Enum.map(paths_rel, &Path.expand/1)
min_path = paths |> Enum.min() |> Path.split()
max_path = paths |> Enum.max() |> Path.split()
min_path
|> Enum.zip(max_path)
|> Enum.take_while(fn {a, b} -> a == b end)
|> Enum.map(fn {x, _} -> x end)
|> Path.join()
end
@spec random_string(non_neg_integer) :: String.t()
defp random_string(len \\ 16) do
"#{Enum.take_random(?a..?z, len)}"
end
end