创建自定义Mix任务(译)

文章目录
  1. 1. 常见API
  2. 2. Namespaced Tasks
  3. 3. 选项解析
  4. 4. 分享任务
    1. 4.1. 作为依赖
    2. 4.2. 把任务打包
    3. 4.3. MIX_PATH

原文: http://elixir-lang.readthedocs.org/en/latest/mix/3/

在Mix中,一个任务实际上是一个具有名称空间Mix.Tasks并实现了run/1函数的模块.例如,compile任务是一个名称为Mix.Tasks.Compile的模块.

创建一个简单的任务:

1
defmodule Mix.Tasks.Hello do
    use Mix.Task
    @shortdoc "这是一个短文档, 看"
    @moduledoc """
    一个测试任务
    """
    def run(_) do
        IO.puts "你好,世界!"
    end
end

保存文hello.ex, 并编译:

1
$ elixirc hello.ex
$ mix hello
你好,世界

上述模块定义了一个名称为hello的任务. 函数run/1接受一个二进制字符串参数, 该参数是从命令行传递给此任务的.

当调用命令mix hello时, 该任务被执行, 并输出你好,世界. Mix使用其第一个参数(hello)查找任务模块并执行run函数.

为什么有一个@moduledoc@shortdoc. 这两个文档标记是被help任务使用来显示任务的说明文档. @shortdoc用在执行mix help的时候显示任务的简短描述, @moduledoc用于执行mix help hello是显示hello任务的详细描述.

除了这两个文档标签外, 还有一个@hidden标签, 当其设置为true时,该任务不显示在mix help的输出中, 任何没有@shortdoc标签的任务也不会显示.

1
defmodule ModuleName do
    @hidden true
end

常见API

当编写任务时, 需要访问一些常见的Mix功能, 如下:

  • Mix.Project.config 返回项目配置(mix.exsproject函数), 如果当前目录不存在mix.exs文件, 该函数返回一个空的配置.
  • Mix.Project.get! 访问当前项目的模块, 需要访问项目中的特殊函数是非常有用. 如果项目未定义,将抛出异常.
  • Mix.shell
  • Mix.Task.run(task,args) 从其他Mix任务中调用另一个任务; 如果该任务已经被调用, 不做任何操作.

Namespaced Tasks

简单的任务可用于完成复杂的事情. 任务实际上也是Elixir代码,任何Elixir可以做的事情都可以放到任务中去做. 可以像分发其他库一样分发任务, 让任务可以在其他项目中重用.

要在多个项目中重用任务, 为了避免名称冲突, Mix任务支持名称空间.

示例:

1
defmodule Mix.Tasks.Mytasks do
    @shortdoc "任务集合模块"
    @moduledoc """
    用于构建和部署的任务集合
    """
    defmodule Build do
        use Mix.Task
        @shortdoc "构建任务"
        @moduledoc """
        构建一个软件组件模块
        """
        def run(_) do
            IO.puts "运行子任务Build"
        end
    end
    defmodule Deploy do
        use Mix.Task

        @shortdoc "部署一个软件组件"
        @moduledoc """
        把一个软件组件部署到服务器
        """
        def run(_) do
            IO.puts "运行子任务Deploy"
        end
    end
end

任务模块写好了后, 可以像这样调用任务: mix mytasks.build, mix mytasks.deploy, 这功能很酷对吧?

任务帮助

选项解析

OptionParser.parse(["--debug"])
#=> { [debug: true], [] }

OptionParser.parse(["--source", "lib"])
#=> { [source: "lib"], [] }

OptionParser.parse(["--source", "lib", "test/enum_test.exs", "--verbose"])
#=> { [source: "lib", verbose: true], ["test/enum_test.exs"] }

分享任务

创建了任务后,如果需要在团队内分享给其他人, 或在其他项目中重用, 这章描述了几种不同的分享法师

作为依赖

假设创建了一个my_tasks项目, 其提供了众多有用的功能, 把该项目添加为其他项目的依赖, 所有在my_tasks项目中的任务可以被其他引用了my_tasks的项目使用.

把任务打包

Mix允许你安装和卸载本地归档包. 要为当前项目生成一个归档包, 运行:

root@0b85dcd174f2:~/elixir/commandlinetools# mix do archive.build
Generated archive commandlinetools-0.0.1.ez with MIX_ENV=dev

把任务打包

打包的任务可以通过文件系统路径或URL安装:

mix archive.install http://localhost/commandlinetools-0.0.1.ez

mix archive命令的的详细说明可通过 mix help archive 查看

MIX_PATH

最有一个中方法是使用MIX_PATH. 设置了MIX_PATH环境变量之后, 所有在其中的任务对Mix都可用, 比如:

$ export MIX_PATH="/elixir/ebin"

这种方式可以单独维护需要在多个项目中使用的任务.