【问题标题】:How do I run a mix task from within a mix task?如何从混合任务中运行混合任务?
【发布时间】:2017-05-30 02:47:46
【问题描述】:

我想在自定义混合任务中运行混合任务。

类似

def run(_) do
  Mix.Shell.cmd("mix edeliver build release")
  #do other stuff

但我不知道如何执行 shell 命令。如果有更简单的方法(除了制作一个 bash 脚本),请告诉我。

【问题讨论】:

    标签: elixir elixir-mix


    【解决方案1】:

    虽然我从未尝试通过 Mix.shell.cmd 从另一个混合任务中运行混合任务,并且我不确定这是否是最佳做法,但看起来像您的目标一样可行:

    def run(args) do
      Mix.Shell.cmd("mix test", fn(output) -> IO.write(output) end)
      # (...)
    end
    

    上面的代码确实通过mix test 运行测试并打印出它们的输出。注意:以上代码基于Mix 1.3.4,界面与1.4.0略有不同。

    虽然可能更优雅的方法是为“复合”任务创建mix alias,其中包括您依赖的任务和您的自定义任务:

    # inside mix.exs
    def project do
      [
        # (...)
        aliases: [
          "composite.task": [
            "test",
            "edeliver build release",
            "my.custom.task",
          ] 
        ]
      ]
    end
    

    现在运行mix composite.task 应该在my.custom.task 之前运行另外两个任务。

    【讨论】:

      【解决方案2】:

      Shell 是这里的冗余链接。如果你想运行edeliver任务,运行Mix.Tasks.Edeliver#run

      def run(_) do
        Mix.Tasks.Edeliver.run(~w|build release|)
        # do other stuff
      

      【讨论】:

        【解决方案3】:

        要执行 shell 命令,您可以使用Loki。您可以找到用于 shell 执行的函数execute/1

        以及我如何在 Mix.Task 中使用来执行其他混合任务的示例:

        defmodule Mix.Tasks.Sesamex.Gen.Auth do
          use Mix.Task
        
          import Loki.Cmd
          import Loki.Shell
        
          @spec run(List.t) :: none()
          def run([singular, plural]) do
        
            execute("mix sesamex.gen.model #{singular} #{plural}")
            execute("mix sesamex.gen.controllers #{singular}")
            execute("mix sesamex.gen.views #{singular}")
            execute("mix sesamex.gen.templates #{singular}")
            execute("mix sesamex.gen.routes #{singular}")
        
            # ...
          end
        end
        

        或者看看它是如何执行命令的:

        @spec execute(String.t, list(Keyword.t)) :: {Collectable.t, exit_status :: non_neg_integer}
        def execute(string, opts) when is_bitstring(string) and is_list(opts) do
          [command | args] = String.split(string)
          say IO.ANSI.format [:green, " *   execute ", :reset, string]
          System.cmd(command, args, env: opts)
        end
        

        希望对你有帮助。

        【讨论】:

          【解决方案4】:

          Mix.Task.run("edeliver build release") 有效

          【讨论】:

            猜你喜欢
            • 2016-09-25
            • 1970-01-01
            • 2012-07-24
            • 2017-05-18
            • 2015-11-13
            • 1970-01-01
            • 1970-01-01
            • 2019-09-20
            • 1970-01-01
            相关资源
            最近更新 更多