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

Posted

技术标签:

【中文标题】在 Clojure 项目中存储项目版本号的常见约定是啥?【英文标题】:What is a common convention for storing a project version number in a Clojure project?在 Clojure 项目中存储项目版本号的常见约定是什么? 【发布时间】:2021-11-25 19:58:21 【问题描述】:

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

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

谢谢!

【问题讨论】:

【参考方案1】:

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

(defproject tupelo/demo "0.1.0-SNAPSHOT"

只需编辑project.clj即可轻松维护。

就在上个月,tools.build 的最终版本发布了,这是使用Deps/CLI 系统发布 JAR 文件的“官方”方式。我还没有机会玩它,但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))

【讨论】:

【参考方案2】:

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

对于应用程序(与 lib 相比),我所做的是将版本存储在 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))))

【讨论】:

我很好奇你为什么不在版本控制中跟踪你的 version.edn 文件。 因为(在我的情况下)它依赖于 git 提交,因此是在生成 uberjar 之前生成的。我确实将 build.clj(包含主要/次要版本)置于版本控制之下。【参考方案3】:
(defproject my.domain/service
  (-> "resources/service.VERSION" slurp .trim)
...

关于 leiningen 项目

【讨论】:

您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。【参考方案4】:

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

deps.edn 世界中的一个约定是将项目版本数据存储在 pom.xml 文件中,该文件可以通过在与 @987654330 相同的目录中调用 clojure -Spom 从您的 deps.edn 文件中生成@ 文件,然后手动或通过脚本编辑该文件中的版本号。 deps 生态系统中的大量工具依赖于 pom.xml 文件的存在,并直接或传递地从该文件中读取版本信息。

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

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

【讨论】:

以上是关于在 Clojure 项目中存储项目版本号的常见约定是啥?的主要内容,如果未能解决你的问题,请参考以下文章

用leiningen来运行和打包clojure项目

eclipse导入项目后出现红色叉号的解决方案

java中版本号的设置

软件项目版本号的命名规则及格式

软件项目版本号的命名规则及格式

软件项目版本号的命名规则及格式