檢視原始碼 Mix.Task 行為 (Mix v1.16.2)

提供便利性,用於建立、載入和操作 Mix 任務。

Mix 任務可以透過在模組中定義 use Mix.Task 來定義,其名稱以 Mix.Tasks. 開頭,且定義了 run/1 函式。通常,任務模組會存在於 lib/mix/tasks/ 目錄中,且其檔案名稱使用點分隔符號,而非底線(例如 deps.clean.ex) - 儘管最終檔案名稱並無關聯。

例如

# lib/mix/tasks/echo.ex
defmodule Mix.Tasks.Echo do
  @moduledoc "Printed when the user requests `mix help echo`"
  @shortdoc "Echoes arguments"

  use Mix.Task

  @impl Mix.Task
  def run(args) do
    Mix.shell().info(Enum.join(args, " "))
  end
end

指令名稱會對應到模組名稱中,緊接在 Mix.Tasks. 之後的區段。例如,模組名稱為 Mix.Tasks.Deps.Clean 會對應到指令名稱 deps.clean

根據使用者的終端機,run/1 函式將會收到傳遞的所有命令列引數清單。

例如,如果檢查上述 echo 任務中的 args,你可能會看到類似這樣的內容

$ mix echo 'A and B' C --test
["A and B", "C", "--test"]

use Mix.Task

當你 use Mix.Task 時,Mix.Task 模組將會設定 @behaviour Mix.Task,並為下方區段中記載的模組屬性定義預設值。

模組屬性

你可以透過設定模組屬性來控制 Mix 任務的某些行為。本區段記載了可用的屬性。

@shortdoc

如果你希望在 mix help 上公開顯示任務,請定義 @shortdoc 屬性。如果你不希望透過 mix help 列出你的任務,請省略此屬性。

@moduledoc

屬性 @moduledoc 可以覆寫 @shortdoc。如果整個模組的說明文件以 @moduledoc false 隱藏,則任務將不會顯示在 mix help 中。

@requirements

如果任務有需求,可以使用屬性 @requirements 列出。需求是此任務需要執行的其他 Mix 任務。例如

@requirements ["app.config"]

任務通常會依賴下列任務之一

  • "loadpaths" - 確保相依性可用且已編譯。如果您要發布任務作為供其他人使用的函式庫的一部分,而且您的任務不需要以任何方式與使用者程式碼互動,則這是建議的需求

  • "app.config" - 另外編譯並載入目前專案的執行時期設定。如果您要建立一個任務在應用程式中使用,或作為函式庫的一部分,而且必須呼叫或與使用者程式碼互動,則這是建議的最低需求

  • "app.start" - 另外啟動目前專案及其相依性的監督樹

@recursive

如果您希望任務在傘狀專案中的每個傘狀子專案執行,請設定 @recursive true

@preferred_cli_env

設定此任務偏好的 Mix 環境。例如,如果您的任務是要用於測試,則可以設定

@preferred_cli_env :test

文件

使用者可以透過執行 mix help my_task 來閱讀公開 Mix 任務的文件。將會顯示的文件是任務模組的 @moduledoc

摘要

回呼函式

任務需要實作 run,它會接收命令列引數清單。

函式

檢查給定的 task 名稱是否為別名。

傳回所有已載入的任務模組。

清除所有已呼叫的任務,讓它們可以再次被呼叫。

接收一個任務名稱,並傳回對應的任務模組(如果存在的話)。

接收一個任務名稱,並取得對應的任務模組。

載入所有程式路徑中的任務。

載入給定 paths 中的所有任務。

取得給定任務 module 的模組文件。

提供向後相容性。

表示目前的任務是否正在遞迴。

檢查任務是否應該在傘狀專案的所有子應用程式中遞迴執行。

重新啟用給定的任務,以便可以在堆疊中再次執行它。

取得給定任務的必要條件清單。

使用給定的引數重新執行 task

使用給定的 args 有條件地執行任務(或別名)。

在傘狀專案的指定子應用程式清單中執行遞迴任務。

取得給定任務 module 的簡短文件。

如果給定的模組是任務,則傳回 true

傳回給定 module 的任務名稱。

類型

@type task_module() :: atom()
@type task_name() :: String.t() | atom()

回呼

@callback run(command_line_args :: [binary()]) :: any()

任務需要實作 run,它會接收命令列引數清單。

函式

@spec alias?(task_name()) :: boolean()

檢查給定的 task 名稱是否為別名。

如果給定的名稱不是別名或不是任務,則傳回 false

有關任務別名的更多資訊,請參閱 Mix 文件中的 "別名" 區段。

@spec all_modules() :: [task_module()]

傳回所有已載入的任務模組。

尚未載入的模組不會顯示。如果您想預載入所有任務,請查看 load_all/0

@spec clear() :: :ok

清除所有已呼叫的任務,讓它們可以再次被呼叫。

此操作不是遞迴的。

@spec get(task_name()) :: task_module() | nil

接收一個任務名稱,並傳回對應的任務模組(如果存在的話)。

如果找不到模組、模組是別名或不是有效的 Mix.Task,則傳回 nil

@spec get!(task_name()) :: task_module()

接收一個任務名稱,並取得對應的任務模組。

例外

@spec load_all() :: [task_module()]

載入所有程式路徑中的任務。

@spec load_tasks([List.Chars.t()]) :: [task_module()]

載入給定 paths 中的所有任務。

@spec moduledoc(task_module()) :: String.t() | nil | false

取得給定任務 module 的模組文件。

傳回模組文件或 nil

此函式已棄用。請在 mix.exs 中設定環境。

提供向後相容性。

連結到此函式

recursing?()

檢視原始碼 (自 1.8.0 起)
@spec recursing?() :: boolean()

表示目前的任務是否正在遞迴。

如果任務標記為遞迴,且在傘狀專案中執行,則傳回 true

@spec recursive(task_module()) :: boolean()

檢查任務是否應該在傘狀專案的所有子應用程式中遞迴執行。

傳回 truefalse

@spec reenable(task_name()) :: :ok

重新啟用給定的任務,以便可以在堆疊中再次執行它。

呼叫此函式時,別名和一般堆疊都會重新啟用。

如果傘狀專案重新啟用任務,則會為所有子專案重新啟用。

連結到此函式

requirements(module)

檢視原始碼 (自 1.11.0 起)
@spec requirements(task_module()) :: []

取得給定任務的必要條件清單。

傳回字串清單,其中字串預期為任務,後面可接其引數。

@spec rerun(task_name(), [any()]) :: any()

使用給定的引數重新執行 task

此函式重新執行給定的任務;為此,它會先重新啟用任務,然後像一般任務一樣執行。

@spec run(task_name(), [any()]) :: any()

使用給定的 args 有條件地執行任務(或別名)。

如果存在與給定任務名稱相符的任務,且尚未呼叫,則會使用給定的 args 執行任務並傳回結果。

如果已為給定的任務名稱定義 別名,則會呼叫別名,而不是原始任務。

如果任務或別名已呼叫,則後續呼叫 run/2 會在不執行的情況下中止,並傳回 :noop

請記住:預設情況下,任務只會執行一次,即使重複呼叫也是如此!如果您需要執行任務多次,您需要透過 reenable/1 重新啟用任務,或使用 rerun/2 呼叫任務。

run/2 會在找不到別名或任務,或任務無效時引發例外。有關更多資訊,請參閱 get!/1

範例

iex> Mix.Task.run("format", ["mix.exs"])
:ok
連結到此函式

run_in_apps(task, apps, args \\ [])

檢視原始碼 (自 1.14.0 起)
@spec run_in_apps(task_name(), [atom()], [any()]) :: any()

在傘狀專案的指定子應用程式清單中執行遞迴任務。

如果任務並非遞迴 (其目的是在子應用程式中執行),則會如常在專案根目錄層級執行。在傘形專案根目錄之外呼叫此函式會失敗。

@spec shortdoc(task_module()) :: String.t() | nil

取得給定任務 module 的簡短文件。

傳回簡短文件或 nil

@spec task?(task_module()) :: boolean()

如果給定的模組是任務,則傳回 true

@spec task_name(task_module()) :: task_name()

傳回給定 module 的任務名稱。

範例

iex> Mix.Task.task_name(Mix.Tasks.Test)
"test"