将Leiningen项目中的版本字符串嵌入应用程序

14

我希望能够查询或嵌入由Leiningen项目设置的版本字符串,并将该值显示给用户。使用情景包括从CLI显示版本字符串,或作为Ring应用程序中的标题。这种做法是否可行?

5个回答

10

如果您正在使用Leiningen运行lein run或类似命令,则可以将其作为系统属性使用:(System/getProperty "myproject.version")。如果您要生成一个jar文件,则需要读取pom.properties


7
我喜欢technomancy的答案,但我不得不去查找如何“读取pom.properties”。结果发现,在maven构件com.example/my-project中,有一个文件存在于类路径下。
META-INF/maven/com.example/my-project/pom.properties

你可以将其读入java.util.Properties中,并获取一个“version”键。

(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")))

提示:如果您的项目中未指定groupid,则Leiningen将其设置为与项目名称相同,因此“META-INF/maven/my-project/my-project/pom.properties”即可完成任务。 - CalderBot

3

有人写了一个很好的库来处理这个问题:https://github.com/trptcolin/versioneer

它适用于lein项目,无论是在lein中运行还是从uberjar中运行。 像以下这样使用它(摘自Github页面):

Add this to your project.clj:

[trptcolin/versioneer "0.2.0"]

Then, in your code, do something like this, where GROUP-ID and ARTIFACT-ID are the usual Leiningen/Maven identifiers for your project.

user=> (require '[trptcolin.versioneer.core :as version])
nil
user=> (version/get-version "GROUP-ID" "ARTIFACT-ID")
"1.2.3-SNAPSHOT"

1

如果您构建了一个jar文件,您可以从jar文件中提取当前版本

否则,如果您没有进行AOT,则可以读取project.clj文件(因为它是一个映射),然后提取版本。

我确信除了编写一个leiningen插件之外,还有更优雅的解决方案(除非有人想要编写这个插件,暗示暗示..)


不幸的是,似乎它不起作用。当使用Java调用一个AOT类上的uberjar时,以下代码返回nil:(println "blargl" (.getSpecificationVersion (.getPackage (class *ns*))) "\n")) - MrEvil

0

以下是我读取项目名称和版本的方法,注意在编译期间会读取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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接