Clojure

Clojure CLI 參考

安裝

Clojure CLI 可透過 Homebrew、bash/posix 腳本或 Powershell 安裝,視平台而定。請參閱 安裝指南 以取得詳細資料,以及 發行頁面 以取得版本資訊。您也可以閱讀 指南 以取得較長的教學課程。如需人工製品建置,請查看 tools.build 指南

任何版本的 Clojure CLI 都可以使用任何版本的 Clojure 語言。一般來說,最好使用最新的 CLI 版本 以取得最新的功能和修正。給定 CLI 版本 A.B.C[.D],REPL 中使用的預設 Clojure 版本 將為 A.B.C,但您可以在相依性中指定較舊(或較新!)的語言版本。

用法

CLI 可透過 clojureclj 呼叫。一般來說,您可以將它們視為可以互換,但 clj 包含 rlwrap 以進行延伸鍵盤編輯,特別適用於 REPL。此參考文件在 REPL 範例中使用 clj,在非 REPL 範例中使用 clojure

每次執行 Clojure CLI 時,都會透過判斷所有路徑、相依性和主要進入點來執行 Clojure 程式,然後在 JVM 上呼叫程式。主要的執行種類是由 -X-T-M(或其不存在)決定的。設定是由一個或多個 deps.edn 檔案結合 命令列選項 定義的。

主要指令

啟動 REPL(預設)
clj [clj-opts] [-A別名]

執行函式 (-X)
clojure [clj-opts] -X[別名] my/fn? [kpath v …​] kv-map?

執行工具 (-T)
clojure [clj-opts] -T[名稱|別名] my/fn [kpath v …​] kv-map?

執行主命名空間或指令碼 (-M)
clojure [clj-opts] -M[別名] [init-opts] [main-opts] [args]

選項索引

exec-opts:
 -Aaliases    Apply aliases
 -X[aliases]  Invoke function, using aliases
 -Ttoolname   Invoke tool by local name
 -T[aliases]  Invoke tool using aliases
 -M[aliases]  Invoke clojure.main, using aliases
 -P           Prepare deps but don't exec

clj-opts:
 -Jopt        Pass JVM option
 -Sdeps EDN   Extra deps.edn data
 -Srepro      Ignore user deps.edn file
 -Spath       Compute and echo classpath
 -Stree       Print dependency tree
 -Scp CP      Use this classpath, ignore deps.edn
 -Sforce      Force classpath computation
 -Sverbose    Print path info
 -Sdescribe   Print env and command parsing info
 -Sthreads    Set specific number of download threads
 -Strace      Write dep expansion trace.edn
 --version    Print version to stdout and exit
 -version     Print version to stderr and exit
 --help -h -? Print this help message

Programs provided by :deps alias:
 -X:deps list          Print deps list+licenses
 -X:deps tree          Print deps tree
 -X:deps find-versions Find available lib versions
 -X:deps prep          Prepare all unprepped libs in deps
 -X:deps mvn-pom       Generate pom.xml for deps.edn
 -X:deps mvn-install   Install maven jar to local repo

啟動 REPL

使用此選項啟動 Clojure REPL。

clj [clj-opts] [-Aaliases]

若要執行 REPL,請在沒有參數的情況下呼叫 clj

這適用於任何目錄,無論是否有 deps.edn。如果您不在 專案目錄 中,所使用的 Clojure 版本將取決於根目錄 deps.edn 中 org.clojure 相依項目的 Clojure 語言版本(將與 CLI 版本號中的版本號相符)或 設定檔目錄 中的使用者 deps.edn(通常未指定)。

若要提供修改 類別路徑JVM 屬性別名,請使用 -A 搭配一個或多個串接的別名關鍵字

clj -A:test

clj -A:test:dev

執行函式 (-X)

Clojure CLI 可以執行專案類別路徑上任何函式,該函式將關鍵字 args 作為輸入,並以映射方式呈現。

clojure [clj-opt*] -X[aliases] [a/fn] [kpath v]* kv-map?

函式執行最終需要下列資訊

  • 類別路徑 - 基於 deps 來源別名

  • 要執行的函式

  • 函式參數的映射

函式及其參數可以透過別名中的資料和/或命令列提供。

別名 可以包含下列 arg 映射金鑰

  • :exec-fn - 如果命令列中未提供函式符號,則使用此函式符號

  • :exec-args - 在執行 exec-fn 時要包含的金鑰對值映射

  • :ns-default - 解析 exec-fn 時要使用的預設命名空間符號

  • :ns-aliases - 解析 exec-fn 時要使用的別名符號對命名空間符號映射

如果要呼叫的函式定義在指定的別名中,則函式在命令列中是選用的。如果在命令列中指定函式符號,則會覆寫別名中的 :exec-fn,並根據別名中的 :ns-default:ns-aliases 解析

:exec-args 形成一個基礎映射,與命令列上的金鑰和值以及尾隨的 kv-map 合併,並按此順序合併。

命令列上的金鑰可以是關鍵字或向量金鑰路徑(與 assoc-in 搭配使用)以指定巢狀金鑰。命令列上的最後一個 arg 是金鑰和值的尾隨映射(選用)。請參閱後面的 金鑰和金鑰路徑引號 部分,以取得關於如何正確指定 edn 金鑰和值的更多詳細資料。

執行工具 (-T)

工具是專案類別路徑外部的功能。使用 -T 執行工具功能與使用 -X 執行專案功能相同,但未包含專案類別路徑。

clojure [clj-opt*] -T[name|aliases] a/fn [kpath v]* kv-map?

在為工具建構類別路徑時,不會包含專案 :deps:paths

工具依賴項會透過工具別名或工具名稱包含。可以為工具安裝短名稱以供使用。已安裝的工具可以使用具有相同使用者設定的任何專案。請參閱 工具安裝 以取得更多詳細資料。

若要按名稱執行工具,請使用 -Ttoolname,例如 -Tlinter。若要按別名執行工具,請使用 -T:linter(別名永遠是關鍵字)。

-X 不同,工具功能必須在命令列中指定,不能在工具別名或已安裝的工具設定中指定。否則,工具功能和引數的指定方式與 -X 在別名和命令列中的指定方式相同。

執行主命名空間或指令碼 (-M)

您可以使用 -M exec-opt 來呼叫 clojure.main,它支援使用 -main 函數或 Clojure 指令碼呼叫命名空間

clojure [clj-opt*] -M[aliases] [main-opts]

-M 別名會從 deps.edn 中提取並組合以形成一個 arg 地圖。arg 地圖可以修改類別路徑或提供 :main-opts,也就是字串主選項的向量。請參閱 clojure.main 頁面以取得有關可用引數的更多資訊。

常見用法

# run single expression:
clojure -M -e '(+ 1 1)'

# run Clojure namespace with main entry point:
clojure -M -m my.app

# run standalone Clojure script
clojure -M script.clj

主選項可以在 別名 中提供,其 arg 地圖金鑰為 :main-opts - 合併別名時,提供的任何 :main-opts 都會取代前一個別名的 :main-opts-M 之後在命令列中的其他選項會附加到合併的別名 arg 地圖中找到的選項。

選項

-Aaliases

-A 會採用一個或多個串接的 別名,它們永遠是簡單或限定的關鍵字,例如 -A:test-A:test:perf/benchmark

雖然 -A 可以與所有執行命令一起使用,但它是唯一可供 REPL 執行 使用的 exec opt,而且這是使用它的最常見原因。

-X[aliases]

-X 接受一個或多個連接的 別名,它們總是簡單或限定關鍵字,例如 -X:test-X:test:perf/benchmark

-X exec-opt 指示 函數執行,且 -X 之後的所有參數都由該執行內容定義。所有 clj-opt(-S-P 等)都應置於 -X 之前。

-Ttoolname, -T[aliases]

-T 接受工具名稱(總是符號,不是關鍵字)或一個或多個連接的 別名,它們總是簡單或限定關鍵字,例如 -T:test-T:test:perf/benchmark

-T exec-opt 指示 工具執行,且 -T 之後的所有參數都由該執行內容定義。所有 clj-opt(-S-P 等)都應置於 -T 之前。

-M[aliases]

-M 接受一個或多個連接的 別名,它們總是簡單或限定關鍵字,例如 -M:test-M:test:perf/benchmark

-M exec-opt 指示 clojure.main 執行,且 -M 之後的所有參數都由該執行內容定義。所有 clj-opt(-S-P 等)都應置於 -M 之前。

-P

在任何其他 exec-opt(-A-X-M-T)之前使用 -P 以執行完整的 deps 展開、下載 deps 並快取類別路徑,但實際上並未執行函數、工具、主程式等。

-Jopt

使用 -J 為應提供給程式的所有 JVM 選項加上前置詞(-J 將會被移除)。例如,-J-Xmx1g-J-XX:+HeapDumpOnOutOfMemoryError-J 可用於執行程式的所有執行模式(repl、-X-T-M)。

另請參閱 JVM 選項 以取得有關提供 JVM 選項的其他方法的更多資訊。

-Sdeps deps

使用 -Sdeps 在命令列中提供額外的 deps.edn 來源。這用於合併中的最後一個 deps 來源。deps 資料需要適當地 引用 以供命令列使用。

-Srepro

使用 -Srepro 從 deps 來源中省略使用者 deps.edn。這會省略任何使用者特定的組態,以確保命令可供其他人重複執行。

Clojure deps 來源

-Spath

使用 -Spath 計算並列印類別路徑。

-Stree

使用 -Stree 計算並列印相依性樹狀結構。請參閱 相依性展開 頁面,以取得有關樹狀結構列印輸出的更多資訊。

-Scp CP

當使用此選項時,不會計算類別路徑,而是改用提供的類別路徑。這在測試或除錯時特別有用。一般而言,您應讓 Clojure CLI 根據 deps.edn 設定計算(並快取)您的類別路徑。

-Sforce

此標記將現有的快取類別路徑(如果有的話)標記為過時。類別路徑將重新計算並快取。

-Sverbose

列印 Clojure CLI 找到並使用的環境和路徑資訊,主要用於偵錯各種設定和快取目錄的位置。

此標記不會變更命令列中可能指定的任何其他執行,因此可將其用於偵錯特定命令的快取檔案位置。

-Sdescribe

列印組態設定為 edn 資料並結束。此功能與 -Sverbose 重疊,但可能對程式化使用有幫助。

-Sthreads N

預設情況下,dep 展開將使用根據處理器數量調整大小的執行緒池執行。使用此設定變更展開期間使用的執行緒數量。設定為 1 將使用單一執行緒串列展開。

-Strace

-Stree-X:deps tree 列印的相依性樹狀結構通常包含足夠的資訊來偵錯為何選擇特定程式庫或程式庫版本。但是,如果您需要更多資訊,此標記會將大量資訊列印到 trace.edn 檔案中,可在 Ask Clojure 中的 tools.deps 提交問題時使用。

--version, -version

將 Clojure CLI 版本列印到 stdout (--version) 或 stderr (-version)。請注意,雖然 Clojure CLI 版本會決定執行中使用的預設 Clojure 版本,但任何版本的 CLI 都可以使用任何版本的 Clojure,而且可以在 deps.edn 檔案中設定 Clojure 版本來變更該版本。

請參閱 工具版本 頁面以取得更多版本和變更日誌資訊。

--help, -h, -?

將說明列印到主控台。另請參閱 man clojure

別名

在專案的內容中呼叫命令時,通常需要指定難以在命令列中引用的複雜資料。身為 Clojure 程式設計師,我們強烈建議使用 Clojure 語法 (edn) 來指定該資料。deps.edn 檔案格式允許我們定義任意 Clojure 資料,並使用 別名 為該資料命名。別名只是命名 edn 資料的關鍵字。

Clojure CLI 的每個執行模式都有許多組態選項(「arg map」)。這些選項可以使用別名透過 edn map 定義,並使用 -A-X-T-M 中的別名在命令列中選取。以下是所有 arg map 鍵的清單 - 除非另有註明,否則這些鍵在所有執行模式中都有效。

  • 專案相依性修改器

    • :extra-deps - 應新增至 root deps 的 lib 至座標的 map

    • :override-deps - 應取代 root deps 中 deps 的 lib 至座標的 map

    • :default-deps - 如果座標在 root 或傳遞式 deps 中為 nil,應使用的 lib 至座標的 map

  • 類別路徑修改器

    • :extra-paths - 字串路徑(或指向相同路徑的關鍵字別名)的向量,用於置於基本路徑之前

    • :classpath-overrides - lib 至字串路徑的 map,用於取代類別路徑上的 lib

  • 工具 deps 和路徑(主要由 -T 使用)

    • :replace-deps(同義字::deps) - 應取代專案 deps 的 lib 至座標的 map

    • :replace-paths(同義字::paths) - 應取代專案路徑的路徑字串的向量

  • JVM 選項

    • :jvm-opts - 作為 jvm 選項傳遞的字串向量

  • 命名空間解析(主要由 -X 和 -T 使用)

    • :ns-aliases - 別名符號至命名空間符號的 map,用於解析符號(例如::exec-fn)

    • :ns-default - 未限定符號(例如::exec-fn)的預設命名空間

  • 函式執行(僅限 -X 和 -T)

    • :exec-fn - 使用 -X 執行的函式

    • :exec-args - 傳遞至 -X 的函式引數(可以在命令列中覆寫)

  • main(僅限 -M)

    • :main-opts - 傳遞至 clojure.main 的字串引數的向量

當提供多個別名時,別名 arg map 中的鍵會合併,語意如下(依串接別名中指定的順序)

  • :extra-deps - 合併

  • :override-deps - 合併

  • :default-deps - 合併

  • :extra-paths - 串接並區分

  • :classpath-overrides - 合併

  • :replace-deps / :deps - 合併

  • :replace-paths / :paths - 串接並區分

  • :jvm-opts - 串接

  • :ns-aliases - 合併

  • :ns-default - 替換 (最後一個獲勝)

  • :exec-fn - 替換 (最後一個獲勝)

  • :exec-args - 如果是映射,則合併,否則替換

  • :main-opts - 替換 (最後一個獲勝)

將別名用於自訂目的

上述別名金鑰對於 Clojure CLI 執行來說是有意義的,但你可以定義任何目的的別名。如果你正在建立一個需要組態的自訂工具,定義一個眾所周知、命名空間化的別名或別名金鑰供你的工具使用,是一個良好的做法。請避免在 deps.edn 檔案中新增頂層金鑰 - 它們可能無法透過程式化工具取得。

由 Clojure CLI 執行的程式會取得執行時的「執行時間基礎」,包括所有別名資料。Clojure 1.12 中新增的 clojure.java.basis API 可用於在程式中於執行時間擷取別名資料。

命名空間解析

在 exec-opts 或 arg 映射 (例如 :exec-fn) 中的符號會根據下列規則解析

  • 如果函式沒有限定,則使用 arg 映射中 :ns-default 金鑰中的命名空間 (如果沒有,則會產生錯誤)

  • 如果函式有限定,且限定詞是 arg 映射中 :ns-aliases 下的別名,則使用該命名空間

  • 否則使用完全限定的函式符號

相依性

每個相依性都以 deps.edn 格式定義,其中包含一個函式庫和座標,多個相依性合併成一個映射 (別名 arg 映射金鑰使用相同的格式)。

deps.edn 來源

Clojure CLI 會透過合併最多四個 deps edn 來源 來建構路徑、相依性和別名的映射。

  • 根相依性 - 定義為嵌入在 tools.deps 函式庫中的資源,將 Clojure 本身定義為唯一的相依性 (版本會與 Clojure CLI 版本相符),以及兩個內建別名::deps:test。包含兩個內建 Maven 儲存庫 - Maven 中央和 Clojars。

  • 使用者相依性 (選用) - 使用者組態目錄 中的 deps.edn 檔案。該檔案一開始是空的,但可能會定義跨專案的其他組態和工具。

  • 專案相依性 (選用) - 目前目錄中的 deps.edn (又稱 專案目錄)

  • 額外相依性 (選用) - 使用 -Sdeps 在命令列中提供

相依性來源會合併成一個單一的 master deps edn,順序如上所列,但下列情況除外

  • -T 工具執行 - 專案 :deps 會被移除,專案 :paths 會被 ["."] 取代

  • -Srepro - 使用者 :deps 會被忽略

合併基本上是 merge-with merge,但 :paths 除外,其中只會使用最後一個 deps 來源的 :paths

類別路徑

JVM 類別路徑包含一系列根目錄,可能是目錄路徑或 jar 檔案路徑。類別(和 Clojure 檔案)會透過套件或命名空間對應到相對於類別路徑根目錄的路徑。例如,java.lang.String 類別可以在路徑 java/lang/String.class 中找到,而 clojure.set Clojure 命名空間可以在路徑 clojure/set.class(適用於 AOT)、clojure/set.cljclojure/set.cljc 中找到。當 JVM 需要載入其中一個檔案時,它會搜尋每個根目錄的相對路徑,並在找到時載入它。

Clojure CLI 會根據下列內容計算類別路徑

最終,所有這些都會合併成

  • 專案路徑

  • 依賴項(外部函式庫及其傳遞依賴項)

專案路徑

合併依賴項和別名 arg 之後,會有來自 deps.edn 的 :paths 和來自別名的 :extra-paths。這兩個都包含向量,且這些向量的順序會保留。額外的路徑總是出現在路徑之前,以便別名可以覆寫專案設定。

請注意,專案路徑和額外路徑都是相對於目前目錄解析的,且應該只參考專案內的路徑,而不是父目錄或同層目錄。目前,參考專案外部會發出警告,但對此的支持已不建議使用,且將在未來移除(改用本機依賴項)。

依賴項擴充

合併依賴項後,會有一組頂層依賴項,而這些依賴項形成依賴項圖形中的根目錄。這個圖形是由上往下探索的,且會使用適當的 採購者(Maven. Git、本機)逐一擴充每個依賴項。會偵測迴圈,且不會再次檢查迴圈。

如果找到同一個函式庫的多個版本,就會進行版本選取程序。依賴項擴充 頁面有關於此程序的更多詳細資訊,但一般來說,會使用函式庫的最新版本。然而,頂層依賴項版本總是會在未修改的情況下使用 - 如果你需要指定特定版本或解決衝突,請在頂層依賴項中設定版本。

依賴項會從頂層依據圖形深度排序,且在每個層級依函式庫名稱進行字母順序排序。

有關 :extra-deps:override-deps:default-deps 等 arg 地圖修改器的更多資訊,請參閱 deps.edn 參考 頁面。

類別路徑建構

類別路徑將包含

  • 額外路徑(相對於專案),依據在最後別名中宣告的順序來指定

  • 來源路徑(相對於專案),依據在最後依賴項中宣告的順序來指定

  • 依賴項路徑(通常是絕對路徑),參考適當採購下載位置中的 JAR 或目錄

    • 依賴項會根據深度從依賴項圖形頂端排序,然後按函式庫名稱字母順序排序

類別路徑可能會進一步透過 arg map 鍵 :classpath-overrides 修改(請參閱 deps.edn 參考)。

您可以使用 -Spath 列印已計算的類別路徑。

JVM 屬性

JVM 屬性有幾個來源

  • 硬式編碼選項:-XX:-OmitStackTraceInFastThrow

  • $JAVA_OPTS 環境變數

  • 別名 arg map 鍵 :jvm-opts(在主依賴項中合併別名)

  • 命令列 -J 選項

所有 JVM 命令列選項會按上述順序串接。在多數情況下,命令列中後面的 JVM 選項會覆寫任何先前的設定,但在所有情況下,串接選項的語意都是 JVM 的語意。不會有選項重複或替換。

CLI 命令

cljclojure 命令是主機特定的指令碼,它們會

  1. 剖析 CLI 參數

  2. (如果沒有快取),啟動 JVM 來計算並快取類別路徑和其他設定

  3. 啟動 JVM 來執行使用者程式,如執行選項 -X-T-M 所指定

步驟 2 是使用 Clojure CLI 安裝的一部分 uberjar 來完成的 - 通常您無法控制該 JVM 的類別路徑或組態(但請參閱 環境變數 以了解一些例外)。

Java

使用 Clojure CLI 時,您預期已安裝 Java,並透過下列幾種方式之一使用 Java。需要 Java 8 或更高版本。任何 Java 發行版都可以使用。

會按下列順序檢查以找到 Java

  • $JAVA_CMD 環境變數

  • $PATH 中的 java

  • $JAVA_HOME/bin/java

如果找不到,CLI 將會停止並顯示錯誤訊息。如果 clj -h 順利完成,表示已找到 Java 可執行檔。

目錄和快取

Clojure CLI 使用幾個重要的目錄,本節說明如何計算這些目錄。

專案目錄

專案目錄是目前的目錄。如果專案目錄包含 deps.edn 檔案,該檔案將會用作 專案 deps 來源

沒有選項可以在遠端專案目錄的內容中執行。

設定檔目錄

設定檔目錄包含

設定檔目錄的計算方式如下

  • 如果設定了 $CLJ_CONFIG,使用該路徑

  • 如果設定了 $XDG_CONFIG_HOME,使用 $XDG_CONFIG_HOME/clojure

  • 否則使用 $HOME/.clojure

如果設定檔目錄不存在,系統會建立該目錄並將下列檔案複製到該目錄

  • deps.edn - 預設使用者 deps.edn(基本上是空的)

  • tools/tools.edn - 內建工具「tools」,用於管理工具

快取目錄

每次執行 CLI 時,都會使用快取目錄來儲存已計算的類別路徑和其他檔案。

快取目錄的計算方式如下

  • 如果目前的目錄有專案 deps.edn,而且目前的目錄可寫入,使用 ./.cpcache

  • 否則使用 設定檔目錄 中的 .cpcache 目錄

快取目錄中的檔案是快取,用於改善使用已計算類別路徑的啟動時間。一般來說,這個快取不應該過期,但你可以使用 -Sforce 在特定指令上強制重新計算,或者如果沒有把握,只要使用 rm 刪除快取目錄即可。

當你安裝 CLI 的新版本時,有時會使快取失效(如果快取金鑰格式已變更),導致你之前執行的指令重新計算類別路徑。

Clojure CLI 絕不會刪除快取目錄中的檔案,因此由你決定是否要定期清除這些目錄。建議在專案的 .gitignore 檔案中包含 .cpcache/,因為該目錄中沒有任何內容對其他專案使用者有幫助。

環境變數

下列環境變數會影響 CLI 執行(許多變數已在本頁的其他地方詳細說明)

  • CLJ_CONFIG - 使用者設定檔目錄,用於儲存使用者 deps.edn、工具設定檔,以及沒有專案 deps.edn 的指令的 cpcache(預設值 = ~/.clojure

  • XDG_CONFIG_HOME - 如果設定此標準變數,將使用 $XDG_CONFIG_HOME/clojure 作為使用者設定目錄

  • CLJ_CACHE - 使用者快取目錄,(預設值 = <config-dir>/.cpcache

  • XDG_CACHE_HOME - 如果設定此標準變數,將使用 $XDG_CACHE_HOME/clojure 作為使用者快取目錄

  • CLJ_JVM_OPTS - JVM 選項,將包含在內部呼叫類別路徑建置程式的過程中,這對於提供某些功能很有用,例如使用自簽憑證的信任儲存來下載內部人工製品

  • JAVA_CMD - 要使用的 Java 可執行檔路徑

  • JAVA_HOME - 如果路徑上沒有 $JAVA_CMDjava,將嘗試使用 $JAVA_HOME/bin/java

  • JAVA_OPTS - 要包含在正在執行的使用者指令中的 JVM 選項 - 未快取。包含在任何 -J 命令列參數和任何 :jvm-opts 之前

  • AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY 和其他 AWS 環境變數在存取基於 S3 的 Maven 儲存庫時使用

  • GITLIBS - gitlibs 儲存目錄的路徑(預設值 = ~/.gitlibs

  • GITLIBS_COMMAND - 要執行的 git 指令(預設值 = git

  • GITLIBS_DEBUG - 設定為 true 以列印所有正在執行的 git 指令

  • CLOJURE_CLI_ALLOW_HTTP_REPO - 設定為 true 以允許 http:// 儲存庫網址(這可能會使您的依賴下載受到中間人攻擊的影響)

金鑰和金鑰路徑

使用 -X-T exec-opts,您可以在命令列上提供金鑰路徑/值對。金鑰路徑是單一金鑰或金鑰向量,用於參照巢狀金鑰(與 assoc-in 相同)。每個金鑰路徑都將用於 assoc-in 到原始 :exec-args 地圖,覆寫那裡的數值。

# Top key override
clj -X:my-fn :val 789

# Nested key override
clj -X:my-fn '[:my :data]' 789

除了在命令列中傳遞金鑰路徑/值對和金鑰路徑之外,還可以將提供值對應的選用地圖作為最後一個引數傳遞。此地圖將與先前提供的金鑰路徑/值對應合併,並可能覆寫這些對應。

# Augment the arguments to my-fn
clj -X:a-tool my-fn :val 789 '{:val2 123}'

# Override the arguments to my-fn
clj -X:a-tool my-fn :val 789 '{:val 123}'

# Single map (no kvs) provides arguments to my-fn
clj -X:a-tool my-fn '{:val 789}'

引用金鑰和值

命令列上的金鑰和值會讀取為 edn。以下資料可以在不引用情況下使用

  • 數字 - 12312.4

  • 布林值 - truefalse

  • Nil - nil

  • 符號 - namefoo/bar

  • 關鍵字 - :id:company/name

這些資料類型需要以單引號包圍

  • 字串 - '"hi there"' - 注意同時使用單引號作為 shell 和雙引號作為 edn 字串讀取

  • 向量 - '[1 2 3]'

  • 映射 - '{:a 1, :b 2}'

  • 集合 - '#{:a :b}'

  • 清單 - '(1 2 3)'

在 Windows 上,WSL2 shell 可以遵循上述建議,但在 cmd.exe 或 Powershell 上,字串值需要額外的跳脫引號。不幸的是,用於轉換命令列 Windows 程式參數的引號規則與 Powershell 引號和字詞拆分的組合非常複雜

若要傳遞頂層字串值,如果字串值沒有空格,可以使用 '\"str\"'。如果字串值有空格(或沒有),應使用 '"""str value"""'

PS D:> clj -X clojure.core/prn :string1 '\"no-spaces\"' :string2 '"""has spaces"""'
{:string1 "no-spaces", :string2 "has spaces"}

對於嵌套在其他集合中的字串值,如果有空格,請使用雙引號;如果沒有,請使用三引號

PS D:> clj -X clojure.core/prn :val '{:s1 """nospaces""" :s2 ""has spaces""}'
{:val {:s1 "nospaces", :s2 "has spaces"}}

程式

Clojure CLI 旨在提供存取其他函式庫中具有其獨立類別路徑的程式(函式)。此功能透過根目錄 deps.edn 中內建的 :deps 別名來擴充功能,此別名提供 tools.deps.cli(請參閱 API)。

相依性清單

---
clj -X:deps list
---

列印為類別路徑選取的所有傳遞相依性的已排序清單,以及授權資訊(如果找到)。其他選項可 used 選擇別名或其他類別路徑修改,或修改列印資訊。

請參閱 API 文件

相依性樹狀結構

---
clj -X:deps tree
---

列印相依性樹狀結構,其中包含在 相依性擴充期間確定的包含/排除資訊。其他選項可 used 選擇別名或其他類別路徑修改,或修改列印資訊。

例如,以下可用於列印 :test 別名的 deps 樹狀結構

---
clj -X:deps tree :aliases '[:test]`
---

請參閱 API 文件

別名清單

---
clj -X:deps aliases
---

此程式會根據目前的 deps 環境列印所有在命令列中可用的別名。其他選項可用於選擇別名或其他類別路徑修改。

請參閱 API 文件

說明函數

help/dochelp/dir 函數會內省工具的使用方式。由於 :deps 別名不包含專案類別路徑,因此當在您自己的專案中執行函數時,這些函數目前並無用處。

  • -X:deps help/doc - 顯示使用關鍵字 :ns 或其他關鍵字 :fn 指定的函數的說明字串和參數清單;如果兩者都沒有給定,則使用 :ns-default

  • -X:deps help/dir - 列印使用關鍵字 :ns 提供的命名空間中的公開函數,如果沒有給定,則使用 :ns-default

列出內建 tools 工具的 :ns-default 中的函數集的範例

clojure -A:deps -Ttools help/dir

列出別名中函數集的範例

clojure -X:deps:my-alias help/dir

列印說明命名空間本身的說明文件(請注意,help:deps:ns-aliases 地圖中定義)

clojure -X:deps help/doc :ns help

準備程式庫

使用 Clojure 來源的來源程式庫可以立即新增到使用它的專案的類別路徑中。但是,有些來源程式庫在新增之前需要一些準備,例如由於需要 Java 編譯,或複製/替換資源檔案等。Clojure CLI 現在將偵測需要準備的專案,並防止在準備步驟完成之前從來源執行程式。

如果您的程式庫需要準備,請將 :deps/prep-lib 關鍵字新增到您的 deps.edn

{:paths ["src" "target/classes"]
 :deps/prep-lib
 {:ensure "target/classes"
  :alias :build
  :fn compile-java}}

:deps/prep-lib 下的關鍵字為

  • :ensure - 目錄存在決定是否需要準備(如果存在,則準備已完成)

  • :alias - 在準備期間使用 -T 呼叫的別名

  • :fn - 在準備期間使用 -T 呼叫的函數

因此,deps.edn 也應該有一個可以執行指定 fn 的別名。請參閱 tools.build 指南,了解如何使用 tools.build 定義具有可呼叫函數的建置指令碼。

如果您將此 git 程式庫新增為相依性並嘗試執行程式,Clojure CLI 將下載它,偵測它需要準備,並且尚未準備(「target/classes」路徑不存在),然後退出。

要找出並「準備」相依樹中的程式庫,你可以使用內建別名 :deps 所提供的 prep 工具

clj -X:deps prep

prep 任務會找出相依擴充中的所有程式庫,並尋找是原始程式庫、需要準備(根據其 :deps/prep-lib 鍵)且尚未準備(根據其 :deps/prep-lib 對應中的 :ensure 目錄)的程式庫。這些程式庫會以別名和函式執行指定在那裡的指令,就像:clj -T:<alias> <fn>

一旦程式庫已準備好,就不需要再由這個 git 程式庫版本的其他使用者準備。

你應該使用準備步驟來編譯你的 Clojure 程式碼嗎?通常不會。機器上這個 git 程式庫的所有使用者都會共用由準備步驟建立的已準備類別路徑。Clojure 編譯器和相依程式庫的選擇最好留給使用這個程式庫的每個應用程式。如需關於使用開發時間編譯的更多資訊,請參閱 開發啟動時間 指南。

尋找版本

要搜尋 Maven 或 git 程式庫的可用版本,請使用內建別名 :deps 所提供的 find-versions 工具

clj -X:deps find-versions ...

可提供的參數有

  • :lib - git 或 Maven 程式庫名稱。git 網址會自動從 git 程式庫名稱建構。例如,io.github.clojure/tools.deps.graph:git/lib 會建構 git 網址 https://github.com/clojure/tools.deps.graph.git。對於 Maven,請使用 Maven 程式庫名稱,例如 org.clojure/tools.deps.graph

  • :tool - 如果工具已安裝,則為工具名稱

find-versions 會將 git 或 Maven 座標列印到主控台,每一行一個。

本機 Maven 安裝

Clojure CLI 提供 -X:deps mvn-install 程式以供方便,且可以使用 -X 來將 jar 安裝到你的本機 Maven 快取中。

安裝參數包括下列選項

Required:
:jar - path to jar file, use pom inside jar by default

To supply an explicit pom file:
:pom - path to pom file (used instead of pom inside the jar)

To generate a minimal pom file:
:lib - qualified symbol like my.org/lib
:version - string
:classifier - string

Other options:
:local-repo - path to local repo (default = ~/.m2/repository)

你可以視需要在命令列上傳遞這些選項的覆寫。

clj -X:deps mvn-install :jar '"/path/to.jar"'

如上所述,edn 字串必須使用雙引號,然後再使用單引號表示外殼。

pom 檔案必須明確提供、從 :lib/:version 產生,或在 .jar 檔案中找到(預設)。

產生 Maven pom

使用以下程式產生或更新現有的 pom.xml,其中包含專案的 deps 和路徑

  • -X:deps mvn-pom - 產生 (或更新現有的) pom.xml,其中包含 deps 和路徑

請參閱 API 文件 以取得更多資訊。

工具

工具是封裝在 lib 中的函式集合。工具函式會在獨立的程序中執行,擁有自己的類別路徑,與專案類別路徑無關。工具函式會接收單一映射引數,並使用 -T 呼叫 (與 -X 樣式執行相同的關鍵值引數語法)。

工具 會透過別名 (其他人可以使用專案共用) 或安裝在電腦上的本機工具名稱 (可以在專案間共用) 來描述。

工具安裝

Clojure CLI 會自動安裝管理工具的工具,名稱為「tools」。提供許多有用的函式

  • install - 安裝或重新安裝工具

  • install-latest - 安裝或重新安裝最新版本的工具

  • list - 列出所有已安裝的工具

  • remove - 移掉已安裝的工具

  • show - 印出工具的資訊和用法

安裝

當您決定要安裝哪個版本的工具時,請使用 install 函式按名稱安裝工具。

clj -Ttools install ...

傳遞給 install-tool 的引數為

  • lib - 值是 coord 映射,如同 deps.edn

  • :as - 工具名稱,將用於後續呼叫

例如

clj -Ttools install io.github.clojure/tools.deps.graph '{:git/tag "v1.0.63"}' :as deps-graph

在 Windows 上,Powershell 中需要額外的 轉義引用

clj -Ttools install io.github.clojure/tools.deps.graph '{:git/tag """v1.0.63"""}' :as deps-graph

請注意,git 依賴項可以在工具安裝時使用 git 函式庫名稱(用於根據慣例形成 git URL)和 git 標籤完整地描述。或者,coord 可能包含明確的 :git/url:git/sha

安裝最新版本

在一個步驟中尋找並安裝最新版本的工具

clj -Ttools install-latest :lib io.github.clojure/tools.deps.graph :as deps-graph

若要將現有工具更新到最新版本,您也可以僅按名稱指定工具

clj -Ttools install-latest :tool deps-graph

列出

列出所有已安裝的工具

clj -Ttools list

移除已安裝的工具

clj -Ttools remove :tool name

工具作者的最佳實務

最佳實務

  • 將您的工具提供為公開 git 函式庫

  • 在一個或多個 Clojure 名稱空間中定義您的工具 API,作為採用映射的函式

  • 在 deps.edn 的根目錄中建立一個 :tools/usage 鍵,其中包含 :ns-default 和/或 :ns-aliases 鍵,以供您的 API 名稱空間使用

  • 標記您的 git 回購以建立版本,使用對使用者而言排序明顯的方案。常見的慣例是使用「v1.2.3」等版本字串。

工具可以為使用者提供這些說明

  • 尋找工具版本:clj -X:deps find-versions :lib io.github.USER/TOOL

  • 使用 clj -Ttools install io.github.USER/TOOL '{:git/tag "VERSION"}' :as NAME 安裝工具

  • 使用 clj -TNAME f args…​ 呼叫工具

函式執行協定

有些工具提供函式,設計用於從另一個程序進行程式化執行,並具有下列限制和預期

  • 函式應採用單一映射引數

  • 結果從函式傳回(如常)

  • 函式引發的例外狀況將導致失敗,且例外狀況資料(例如 Throwable→map)將傳達給外部程序,該程序將在 ex-info 中重新引發它

  • 列印輸出(預設)不會被擷取

  • 任何結果或例外狀況資料都應安全地列印並讀回至另一個程序中的資料

有幾個引數映射鍵在 -X 或 -T 期間對 Clojure CLI 具有特殊意義。所有這些鍵都將在呼叫函式之前從引數映射中移除

  • :clojure.exec/invoke - true 表示使用此協定

  • :clojure.exec/out - true 表示在函式執行期間擷取並傳回 stdout

  • :clojure.exec/err - true 表示在函式執行期間擷取並傳回 stderr

結果會包裝到已列印的封套映射中,其中包含下列鍵,並透過 CLI stdout 傳回

  • :tag - :ret:err,視函式傳回結果或引發例外狀況而定

  • :val - 回傳值或例外資料,印成字串

  • :out - 如果要求,擷取 stdout 回傳

  • :err - 如果要求,擷取 stderr 回傳

  • :ms - 函式執行時間(毫秒)

Clojure 1.12.0-alpha2 之後提供此協定的消費者 API。

取得者

取得者會詮釋相依性座標,了解特定座標類型,並知道如何尋找相依性,以及下載函式庫的成品。Clojure CLI 目前支援下列取得者:MavenGitlocal(包含目錄和 jar)。當 tools.deps 函式庫作為函式庫使用時,會支援取得者擴充功能。

座標屬性會決定使用哪個取得者。一般來說,大多數取得者屬性會根據取得者類型進行限定(有少數例外)。與取得者無關的座標屬性會使用 deps 限定詞。

有些取得者也可能會在 deps.edn 組態對應中,使用相同限定詞尋找根目錄的組態屬性。

Maven

Maven 取得者使用限定詞 mvn,用於從 Maven 存放庫 擷取函式庫成品,它是 Java 生態系統中的標準存放庫管理員。函式庫會以 .jar 檔案下載,並儲存在 Maven 本地存放庫快取中(預設位於 ~/.m2/repository)。其他基於 JVM 的工具也可能會使用此快取。

請參閱 deps.edn 說明,了解 Maven 座標類型Maven 取得者組態 的詳細資訊。

Maven 驗證存放庫

對於驗證存放庫中的 Maven 相依性,現有的 Maven 基礎架構用於傳達憑證。

在您的 ~/.m2/settings.xml

<settings>
  ...
  <servers>
    <server>
      <id>my-auth-repo</id>
      <username>zango</username>
      <password>123</password>
    </server>
    ...
  </servers>
  ...
</settings>

然後在您的 deps.edn 中包含一個與伺服器 ID 相符名稱的存放庫(這裡是 my-auth-repo

{:deps
 {authenticated/dep {:mvn/version "1.2.3"}}
 :mvn/repos
 {"my-auth-repo" {:url "https://my.auth.com/repo"}}}

然後在 :deps 中照常參照您的相依性。

Maven S3 存放庫

mvn 採購者也支援連線到 AWS S3 中所主辦的公開和私人 Maven 儲存庫。這在從 AWS 上所主辦的應用程式中存取私人 Maven 儲存庫時特別有用。

加入包含 s3 儲存庫根目錄的 :mvn/repos

{:deps
 {my/library {:mvn/version "0.1.2"}}
 :mvn/repos
 {"my-private-repo" {:url "s3://my-bucket/maven/releases"}}}

S3 儲存區特定於它們所建立的 AWS 區域。s3 傳輸器會嘗試找出儲存區的位置。如果這無法運作,您可以明確地在網址中指定儲存區區域:"s3://my-bucket/maven/releases?region=us-west-2"

對於經過驗證的儲存庫,AWS 認證資料可以逐伺服器基礎設定在 ~/.m2/settings.xml 中,或會從 AWS 認證資料鏈(環境變數等)中環境載入。deps.edn 中的儲存庫名稱必須與 settings.xml 中的伺服器 ID 相符

<settings>
  ...
  <servers>
    <server>
      <id>my-private-repo</id>
      <username>AWS_ACCESS_KEY_HERE</username>
      <password>AWS_SECRET_ACCESS_KEY_HERE</password>
    </server>
    ...
  </servers>
  ...
</settings>

AWS S3 認證資料可以使用下列其中一種機制設定在環境中

  1. 設定環境變數 AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY

  2. 在 AWS 認證資料檔案 ~/.aws/credentials 中建立預設設定檔(較舊的 ~/.aws/config 也支援)。

  3. 在 AWS 認證資料檔案中建立命名設定檔,並設定環境變數 AWS_PROFILE 為其名稱。

  4. Amazon ECS 容器和執行個體設定檔認證資料也應該可以運作,但尚未經過測試。

如需更多資訊,這份 AWS 文件 中的大部分建議說明如何找出認證資料。不過請注意,Java 系統屬性選項不會與 Clojure CLI 一起運作(但如果直接使用 tools.deps 函式庫,則會運作)。

Maven 代理伺服器

在透過代理伺服器存取網際網路的環境中,~/.m2/settings.xml 中現有的 Maven 組態用於設定代理伺服器連線

<settings>
  ...
  <proxies>
    <proxy>
      <id>my-proxy</id>
      <host>proxy.my.org</host>
      <port>3128</port>
      <nonProxyHosts>localhost|*.my.org</nonProxyHosts>
    </proxy>
  </proxies>
  ...
</settings>

參閱 Maven 使用代理伺服器的指南 以取得進一步的詳細資料。

Maven HTTP 標頭

如需將自訂標頭加入傳出的 HTTP 要求,會使用 ~/.m2/settings.xml 中現有的 Maven 組態。

<settings>
  ...
  <servers>
    <server>
      <id>my-token-repo</id>
      <configuration>
        <httpHeaders>
          <property>
            <name>Private-Token</name>
            <value>abc123</value>
          </property>
        </httpHeaders>
      </configuration>
    </server>
    ...
  </servers>
  ...
</settings>

settings.xml 中的伺服器 ID 必須與 deps.edn 中的儲存庫名稱相符

{:mvn/repos
 {"my-token-repo" {:url "https://my.auth.com/repo"}}}

此機制由使用權杖(而非使用者名稱和密碼)進行驗證的儲存庫使用。

Git

git 採購者支援直接使用 Git 儲存庫中所主辦的基於來源的程式庫。預設會將 Git 程式庫下載到 ~/.gitlibs 目錄。會簽出工作樹,並為包含為相依項的每個 sha 快取。

有關 Git 座標類型 的詳細資訊,請參閱 deps.edn 參考。

組態和除錯

git 採購者會使用命令列 git(和 ssh)。需要 git >= 2.5。一般來說,如果命令列可以存取,就應該可以使用 Clojure CLI。預期已安裝 Git,而且預設情況下,git 應該在路徑中。對於 ssh 存取,請參閱系統文件(通常您會在 ~/.ssh/id_rsa 中註冊 ssh 金鑰)。

可以設定以下環境變數來控制 git 使用方式

  • GITLIBS - gitlibs 儲存目錄的路徑(預設值 = ~/.gitlibs

  • GITLIBS_COMMAND - 執行 git 存取的指令(預設值 = git

  • GITLIBS_DEBUG - 設定為 true 以查看正在執行的實際 git 指令及其輸出的記錄(預設值 = false

本地

local 採購者會將本機目錄或 jar 檔案包含為相依性。有關 local 座標類型 的詳細資訊,請參閱 deps.edn 參考。

詞彙表

函式庫

Clojure 或其他程式碼的集合,用於解決某些問題,在單一目錄根目錄下管理。在典型(但非專屬)用法中,大多數 GitHub 回應儲存庫包含單一函式庫。每個函式庫都有不同的命名空間名稱 - 在 Maven 中,這是由群組 ID/人工製品 ID 決定。

人工製品

在容器檔案中發布的函式庫,擷取函式庫在某個時間點的狀態,可能經過某些建置程序,標記版本,包含記錄其相依性的清單,並封裝在例如 jar 中。

座標

選擇用於使用的特定函式庫版本,並包含取得和使用函式庫的足夠資訊。

相依性

在專案/函式庫層級的表達式,宣告函式庫需要宣告函式庫才能提供某些功能。至少必須指定函式庫名稱,也可能指定版本和其他屬性。實際(功能)相依性更細緻。

相依類型

  • Maven 人工製品(基於人工製品)

  • Git 函式庫(基於來源)

  • 本機函式庫(基於來源) - 本機目錄

  • 本機人工製品(基於人工製品) - 本機 jar 檔案

類別路徑(和根目錄/路徑)

本機「位置」(檔案系統目錄和/或 jar)的有序清單,將形成執行時期需要/匯入搜尋的根路徑,作為控制語意的 Java 參數提供。我們不鼓勵類別路徑中依賴順序,這表示命名空間或資源檔案已重複(因此可能會損毀)。

擴充

給定一組根相依性,傳遞相依性集合的完整封閉。

解析

給定一組根相依性和其他修改,建立一個完全擴充的相依性樹狀結構,然後產生從每個提到的函式庫到要使用的單一版本(滿足所有相依項)的對應,以及到該來源或人工製品的本機路徑。我們也會為每個項目包含這些相依項。只有當函式庫依賴不同函式庫的主要版本時,才會產生衝突。

版本

一種由慣例決定其解釋的人類編號系統,通常為 x.y.z。一種流行的方案是「語意版本控制」,又稱「semver」,它為每個層級的變更賦予意義,例如第一個主要數字的變更表示重大變更。

版本差異

當相依性擴充包含同一個函式庫,但指定了多個「版本」,且存在相對順序(依數字或 sha 等)時,就會發生這種情況。當可以建立這種關係時,版本差異可透過選擇「較新的」或「最新的」版本來解決。

版本衝突

當相依性擴充包含同一個函式庫,但有多個「版本」,以致於無法自動選擇最佳選項時,就會發生版本衝突。

  • semver 版本中斷(主要版本已變更)

  • 不包含任何共用根或祖先的 github sha(例如,不同分支或不相關儲存庫上的兩個 sha)

  • 跨不同儲存庫或儲存庫類型的版本,以致於無法建立相對關係

Maven 儲存庫

函式庫成品的儲存庫,例如 Maven central 或 Clojars