檢視原始碼 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
的任務名稱。
類型
回呼
函式
檢查給定的 task
名稱是否為別名。
如果給定的名稱不是別名或不是任務,則傳回 false
。
@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()
接收一個任務名稱,並取得對應的任務模組。
例外
Mix.NoTaskError
- 如果找不到任務,則會引發Mix.InvalidTaskError
- 如果任務不是有效的Mix.Task
,則會引發
@spec load_all() :: [task_module()]
載入所有程式路徑中的任務。
@spec load_tasks([List.Chars.t()]) :: [task_module()]
載入給定 paths
中的所有任務。
@spec moduledoc(task_module()) :: String.t() | nil | false
取得給定任務 module
的模組文件。
傳回模組文件或 nil
。
提供向後相容性。
@spec recursing?() :: boolean()
表示目前的任務是否正在遞迴。
如果任務標記為遞迴,且在傘狀專案中執行,則傳回 true
。
@spec recursive(task_module()) :: boolean()
檢查任務是否應該在傘狀專案的所有子應用程式中遞迴執行。
傳回 true
或 false
。
@spec reenable(task_name()) :: :ok
重新啟用給定的任務,以便可以在堆疊中再次執行它。
呼叫此函式時,別名和一般堆疊都會重新啟用。
如果傘狀專案重新啟用任務,則會為所有子專案重新啟用。
@spec requirements(task_module()) :: []
取得給定任務的必要條件清單。
傳回字串清單,其中字串預期為任務,後面可接其引數。
使用給定的引數重新執行 task
。
此函式重新執行給定的任務;為此,它會先重新啟用任務,然後像一般任務一樣執行。
使用給定的 args
有條件地執行任務(或別名)。
如果存在與給定任務名稱相符的任務,且尚未呼叫,則會使用給定的 args
執行任務並傳回結果。
如果已為給定的任務名稱定義 別名,則會呼叫別名,而不是原始任務。
如果任務或別名已呼叫,則後續呼叫 run/2
會在不執行的情況下中止,並傳回 :noop
。
請記住:預設情況下,任務只會執行一次,即使重複呼叫也是如此!如果您需要執行任務多次,您需要透過 reenable/1
重新啟用任務,或使用 rerun/2
呼叫任務。
run/2
會在找不到別名或任務,或任務無效時引發例外。有關更多資訊,請參閱 get!/1
。
範例
iex> Mix.Task.run("format", ["mix.exs"])
:ok
在傘狀專案的指定子應用程式清單中執行遞迴任務。
如果任務並非遞迴 (其目的是在子應用程式中執行),則會如常在專案根目錄層級執行。在傘形專案根目錄之外呼叫此函式會失敗。
@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"