我希望能够查询或嵌入由 leiningen 项目设置的版本字符串并将该值显示给用户。用途包括显示来自 CLI 的版本字符串,或作为环应用程序中的标头。这可能吗?
5 回答
如果你在 Leiningen usinglein run
等内部运行,它可以作为系统属性使用:(System/getProperty "myproject.version")
. 如果你正在生产一个罐子,你需要阅读pom.properties
.
我喜欢technomancy的答案,但我不得不去查找如何“阅读pom.properties
”。原来对于maven神器com.example/my-project,在classpath下有一个文件
META-INF/maven/com.example/my-project/pom.properties
您可以读入 java.util.Properties 并获取“版本”密钥。
(ns com.example.version
(:require [clojure.java.io :as io])
(:import (java.util Properties)))
(defn read-project-version [groupid artifact]
(-> (doto (Properties.)
(.load (-> "META-INF/maven/%s/%s/pom.properties"
(format groupid artifact)
(io/resource)
(io/reader))))
(.get "version")))
有人写了一个很好的库来处理这个:https ://github.com/trptcolin/versioneer
它适用于 lein 项目,既可以在 lein 中运行,也可以从 uberjar 中运行。像下面这样使用它(取自 Github 页面):
将此添加到您的 project.clj:
[trptcolin/versioneer "0.2.0"]
然后,在您的代码中,执行类似这样的操作,其中 GROUP-ID 和 ARTIFACT-ID 是您项目的常用 Leiningen/Maven 标识符。
user=> (require '[trptcolin.versioneer.core :as version]) nil user=> (version/get-version "GROUP-ID" "ARTIFACT-ID") "1.2.3-SNAPSHOT"
如果您构建一个 jar 文件,您可以从 jar 文件中提取当前版本。
否则,如果您不进行 AOT,则可以read
使用 project.clj 文件(因为它是地图),然后提取版本。
我当然希望有一个更优雅的解决方案,而不是为此编写一个 leiningen 插件(除非其他人想写这个,提示提示..)
这是我读取项目名称和版本的方式,请注意project.clj
在编译期间读取文件,jar 文件只包含字符串:
(defmacro proj-version []
(some->> (slurp "project.clj") clojure.edn/read-string (drop 1) (take 2) (str/join " ")))
(defn -main []
(println (proj-version))
所以对于(defproject abc "1.2.3" ...
,当你运行-main
它会打印:
abc 1.2.3