简体   繁体   中英

Running arbitrary commands in mix

I've got some protocol buffers definitions, in proto/*.proto . My current Makefile-based build system compiles each of them into an Erlang module and header, and into a self-descriptor (as a .pb file) and then embeds the descriptor as a BEAM module:

foo.proto -> foo_pb.erl, foo_pb.hrl
          -> foo.pb -> foo_pb_desc.beam

I've implemented a mix_protobuffs task to do the first step, and the foo.proto -> foo.pb part-step.

I've also got the relevant code for embedding an arbitrary file into an Erlang module -- inspired by this answer -- but I'm wondering about the recommended way of integrating it into my mix-based build process.

Similarly, I've got some other files that need to be processed and then embedded, which suggests that I shouldn't make the mix_protobuffs task know about embedding.

So I guess I'm asking: is there a way to have mix run arbitrary commands pre/post another task?

The common way would be to define your own compiler. For that, you are to create a module in Mix.Task.Compiler namespace and implement Mix.Task.Compiler behaviour. Also the project/0 function of your mix.exs should be updated to return your new compiler. Somewhat like below would do.

defmodule Mix.Tasks.Compile.Protobufs do
  use Mix.Task.Compiler

  @recursive true

  @impl Mix.Task.Compiler
  def run(argv) do
    # do your compilation, possibly with System.cmd/3
    :ok
  end
end

And in your project file:

def project do
  [
    compilers: Mix.compilers() ++ [:protobufs],
    # ...
  ]
end

You also can call any existing mix task from your own task, like Mix.Tasks.Run.run(args) .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM