简体   繁体   English

如何在混合任务中运行混合任务?

[英]How do I run a mix task from within a mix task?

I would like to run a mix task from within a custom mix task. 我想在自定义组合任务中运行混合任务。

Something like 就像是

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

But I cannot figure out how to execute a shell command. 但我无法弄清楚如何执行shell命令。 If there is any easier way (besides just making a bash script), let me know. 如果有更简单的方法(除了制作一个bash脚本),请告诉我。

Shell is the redundant link here. Shell是这里的冗余链接。 If you want to run edeliver task, run Mix.Tasks.Edeliver#run : 如果要运行edeliver任务,请运行Mix.Tasks.Edeliver#run

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

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

For executing shell comand you can use Loki . 要执行shell命令,您可以使用Loki You can find functions for shell execution execute/1 . 您可以找到shell execute/1函数。

And example how I used in Mix.Task for executing other mix tasks: 以及我在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

Or just look how it execute command: 或者只看它如何执行命令:

@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

Hope it help you. 希望它对你有所帮助。

While I never tried running a mix task via Mix.shell.cmd from inside another mix task and I'm not sure if it's best practice, it seems like something like what you're aiming for would work: 虽然我从来没有尝试通过Mix.shell.cmd从另一个混合任务中运行混合任务,但我不确定它是否是最佳实践,看起来像你想要的东西会起作用:

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

The above code does run the tests via mix test and prints out their output. 上面的代码确实通过mix test运行mix test并打印出它们的输出。 Note: the above code is based on Mix 1.3.4, the interface is slightly different in 1.4.0. 注意:上面的代码基于Mix 1.3.4,界面在1.4.0中略有不同。

What might be a more elegant approach though would be creating a mix alias for a "composite" task, consisting of the tasks you depend on and your custom one: 可能更优雅的方法是为“复合”任务创建混合别名 ,包括您依赖的任务和自定义任务:

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

Now running mix composite.task should run the two other tasks before my.custom.task . 现在运行mix composite.task应该在my.custom.task之前运行另外两个任务。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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