在 Clojure 项目中存储项目版本号的常见约定是什么?

What is a common convention for storing a project version number in a Clojure project?

我们的团队正在处理使用 deps.edn

的 Clojure 项目

我们习惯于将版本号存储在 package.json 文件中的 NPM 项目。看起来 Leiningen 用户之前可能已经将版本号存储在 project.clj 文件中。是否有针对 Clojure 项目版本控制的社区范围的约定?我看到人们和 official docs 提到使用 Git 标签,但想知道是否有一些流行的方式让开发人员使用 deps.edn 将版本号存储在文件中。

谢谢!

到目前为止,我只使用 Leiningen 发布 JAR 文件。在这种情况下,版本字符串位于文件的顶部,如

(defproject tupelo/demo "0.1.0-SNAPSHOT"

只需编辑 project.clj.

即可轻松维护

就在上个月,tools.build was released, which is the "official" way of publishing JAR files using the Deps/CLI system. I haven't had a chance to play with it yet but the example in the guide 的最终版本展示了如何在构建 JAR 文件时包含版本字符串。该示例甚至使用了一种基于 git.

中的提交计数的自动化技术
(ns build
  (:require [clojure.tools.build.api :as b]))

(def lib 'my/lib1)
(def version (format "1.2.%s" (b/git-count-revs nil)))
(def class-dir "target/classes")
(def basis (b/create-basis {:project "deps.edn"}))
(def jar-file (format "target/%s-%s.jar" (name lib) version))

(defn clean [_]
  (b/delete {:path "target"}))

(defn jar [_]
  (b/write-pom {:class-dir class-dir
                :lib lib
                :version version
                :basis basis
                :src-dirs ["src"]})
  (b/copy-dir {:src-dirs ["src" "resources"]
               :target-dir class-dir})
  (b/jar {:class-dir class-dir
          :jar-file jar-file}))

我不知道有没有既定的约定,但这是我使用的。

对于应用程序(与库相反),我所做的是将版本存储在 resources/version.edn 中(不受版本控制)并将其作为应用程序配置的一部分读取在启动期间。我使用 major.minor.gitcount 版本控制,但您可以轻松更改它以满足您的需要。我使用 juxt/aero 进行配置管理,但任何类似的库或定制的配置管理都应该有效。这是我的 build.clj.

的摘录
(ns build
  "A build script for myapp."
  (:require [clojure.tools.build.api :as b]
            [org.corfield.build :as bb]))

(def major-version 0)
(def minor-version 2)
(def app 'com.myorg/myapp)
(def main 'com.myorg.myapp)
(def version (format "%d.%d.%s" major-version minor-version (b/git-count-revs nil)))
(def version-file "resources/version.edn")

(defn uber [opts]
  (b/write-file {:path version-file :content {:version-string version}})
  (-> opts
      (assoc :lib app :version version :main main)
      (bb/uber)))

这是我的 config.edn 的摘录(针对 juxt/aero

{:app-config #merge [{:name "My App Name"
                      :credentials-file-path #or [#env CRED_PATH #join [#env HOME "/credentials.json"]]
                      :other-config "something"
                      }
                     #include "version.edn"]
}

而且,-main 函数看起来像

(defn -main
  [& args]
  (try
    (log/info "")
    (log/info ">>>>>>>>>>>>>>>>> Starting Log >>>>>>>>>>>>>>>>>")
    (let [{:keys [options arguments exit-message ok?]} (validate-args args cli-options)]
      (log/debug "Options:" options)
      (log/debug "Arguments:" arguments)
      (cond exit-message
            (exit (if ok? 0 1) exit-message)
            ;;
            :else
            (let [system-config (config/system-config :prod options)]
              (log/info "Initializing My App.")
              (cond (not (config/config-valid? system-config)) (exit 1 (config/explain-config system-config))
                    (:version options) (exit 0 (str "Version: " (config/app-version-string system-config)))
                    :else
                    (start-the-system)
                    ))
    (catch Exception e (log/error e))))
(defproject my.domain/service
  (-> "resources/service.VERSION" slurp .trim)
...

莱宁根项目

我会说这取决于您要存储的版本号的预期用途,以及您使用的工具链。由于您显然没有使用 Lein,因此此答案不会引用与 Lein 相关的任何成语。

deps.edn 世界的惯例是将项目版本数据存储在 pom.xml 文件中,该文件可以通过调用 [=13] 从 deps.edn 文件生成=] 在与 deps.edn 文件相同的目录中,然后手动或通过脚本编辑该文件中的版本号。 deps 生态系统中的大量工具依赖于 pom.xml 文件的存在,并直接或间接地从该文件中读取版本信息。

不幸的是,XML 在 Clojure 中的交互不是很符合人体工程学,所以如果您需要在项目的 运行 代码中解析版本,这可能有点麻烦滋扰。为了实现这一点,我在POM和其他地方的Clojure中看到了之前(不理想)多个版本的独立维护,我看到POM作为资源读入并解析出版本,我看到像[=18=这样的库] 也用过。

我个人建议在您的情况下使用 versioneer,它将遍历系统属性,然后遍历 pom.properties 文件,寻找版本。 source 简单易懂。 depstartools.build 都会生成一个 pom.properties 版本管理员可以读取的文件。