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. If there is any easier way (besides just making a bash script), let me know.
Shell is the redundant link here. If you want to run edeliver
task, run 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 . You can find functions for shell execution execute/1
.
And example how I used in Mix.Task for executing other mix tasks:
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:
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. Note: the above code is based on Mix 1.3.4, the interface is slightly different in 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
.
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.