在 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 项目中存储项目版本号的常见约定是啥?的主要内容,如果未能解决你的问题,请参考以下文章