【问题标题】:Running arbitrary commands in mix混合运行任意命令
【发布时间】:2019-11-27 15:03:21
【问题描述】:

我在proto/*.proto 中有一些协议缓冲区定义。我当前基于 Makefile 的构建系统将它们中的每一个编译成 Erlang 模块和头文件,并编译成自描述符(作为 .pb 文件),然后将描述符嵌入为 BEAM 模块:

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

我已经实现了一个mix_protobuffs 任务来执行第一步,以及foo.proto -> foo.pb 部分步骤。

我还有将任意文件嵌入 Erlang 模块的相关代码——受this answer 的启发——但我想知道将它集成到我的基于混合的构建过程中的推荐方法。

同样,我还有一些其他文件需要处理然后嵌入,这表明我不应该让mix_protobuffs 任务知道嵌入。

所以我想我在问:有没有办法在另一个任务之前/之后混合运行任意命令?

【问题讨论】:

    标签: elixir elixir-mix


    【解决方案1】:

    常见的方法是定义自己的编译器。为此,您将在Mix.Task.Compiler 命名空间中创建一个模块 实现Mix.Task.Compiler 行为。您的mix.exsproject/0 函数也应该更新以返回您的新编译器。像下面这样就可以了。

    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
    

    在你的项目文件中:

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

    您还可以从自己的任务中调用任何现有的mix 任务,例如Mix.Tasks.Run.run(args)

    【讨论】:

    • 我已经实现了Mix.Tasks.Compile.Protobuff;这是我感兴趣的第二个(常见)部分。最后,我实现了Mix.Tasks.Compile.Embed,并让它从project()[:embed]读取通配符,然后将其放在compilers()列表中的适当位置。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-26
    • 2014-04-18
    • 2020-09-20
    • 1970-01-01
    • 1970-01-01
    • 2017-05-30
    • 1970-01-01
    相关资源
    最近更新 更多