I don't know that there is an established convention, but this is what I use.
For an app (in contrast to a lib) what I've done is store the version in resources/version.edn
(which is NOT kept under version control) and read that as part of the config of the app during startup. I use the major.minor.gitcount
versioning, but you can change that easily to suit your needs. I use juxt/aero
for configuration management, but any similar library or bespoke config management should work. Here is an excerpt from my 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)))
Here is an excerpt from my config.edn
(for 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"]
}
And, the -main
function looks like
(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))))