在repl中获取当前clojure项目的版本

24

在Clojure的REPL中,是否可以获取项目信息?

例如,如果有一个定义好的项目:

(defproject blahproject "0.1.2" ....)

当在项目目录中运行 REPL 时,是否有类似于这样的函数?

> (project-version) 
;=> 0.1.2 

如果您只需要项目版本,则在此处提到:https://dev59.com/3mgu5IYBdhLWcg3wkHyP - ktsujister
8个回答

18

虽然你可以自己解析 project.clj,但这可能很麻烦。而且工作量很大。相反,你可以采取以下方法:

(System/getProperty "projectname.version")

12
在REPL中可以运行,但在uberjar中无法运行。 - Dan Ross
@DanRoss 这个可以用来检测当前程序是否是从 repl 启动的吗?还是有更简单/更可靠的方法? - David Ongaro

14

Leiningen项目文件只是Clojure数据 :)

(-> "/path/to/project.clj" slurp read-string (nth 2))

(注意:此处的HTML标记不应被翻译)

1
只需使用(some-> (io/resource "project.clj") slurp edn/read-string (nth 2)) - joelittlejohn
3
从您的类路径中获取任意project.clj的机会很高。我得到了clj-time/clj-time,而我甚至没有明确地拉入这个库。小心从黑暗盒子里伸手去随意取出物品。 - pete23
@pete23 说得好。如果你用 lein 构建了 jar,那么你也可以使用 (some->> (io/resource "META-INF/maven/myproject/myproject/pom.properties") slurp (re-find #"version=(.*)") second) - joelittlejohn

11

我使用environ (https://github.com/weavejester/environ),它可以从多个来源获取设置,包括系统属性。 项目版本显示为:<project-name>-version

foobar.repl=> (require '[environ.core :refer [env]])
nil
foobar.repl=> (:foobar-version env)
"0.1.0-SNAPSHOT"

9

如在此讨论中所述。

(ns myproject.example
  (:require [clojure.java.io :as io])
  (:import java.util.Properties))

(defn get-version [dep]
  (let [path (str "META-INF/maven/" (or (namespace dep) (name dep))
                  "/" (name dep) "/pom.properties")
        props (io/resource path)]
    (when props
      (with-open [stream (io/input-stream props)]
        (let [props (doto (Properties.) (.load stream))]
          (.getProperty props "version"))))))

(get-version 'myproject) ; => 0.1.0
(get-version 'org.clojure/clojure) ; => 1.3.0

9
将以下代码添加到project.clj的末尾:
(def project (assoc-in project [:repl-options :init]
                       `(~'def ~'project-version ~(project :version))))

现在,你的REPL(读取-求值-输出循环)初始命名空间中将有一个名为project-version的变量。

7

vemv所说,Leiningen项目文件只是Clojure数据。因此,很容易将您的项目作为普通的哈希映射进行访问:

(->> "project.clj"
     slurp
     read-string
     (drop 2)
     (cons :version)
     (apply hash-map)
     (def project))

如果你只需要在repl中使用这个变量,你可以将它添加到project.cljrepl-options中:
(defproject yourproject "0.1.0"
  :description ""
  :url ""
  :dependencies [ [org.clojure/clojure  "1.4.0"]]
  :repl-options { :init (->>  "project.clj"
                              slurp
                              read-string
                              (drop 2)
                              (cons :version)
                              (apply hash-map)
                              (def project))})

现在,您的repl中有一个project变量。因此,要访问您的项目版本,您只需键入(:version project)
当然,您可以简单地使用本机Leiningen代码解析您的项目文件:
(defproject yourproject "0.1.0"
  :description ""
  :url ""
  :dependencies [ [org.clojure/clojure  "1.4.0"]
                  [leiningen-core       "2.1.3"]]
  :repl-options { :init (do (require 'leiningen.core.project)
                            (def project
                                 (leiningen.core.project/read)))})

但是,如果你只需要你的项目版本而不需要其他内容,那么最好使用Ankur的解决方案。


7

如果您需要更加全面的方案,可以看一下Leiningen的configleaf插件(https://github.com/davidsantiago/configleaf)。它将使项目映射与活动配置文件合并后,可在您选择的命名空间中向项目代码提供访问。


0
如果您需要从ClojureScript执行此操作,您可以创建一个宏(来自另一个Clj文件),并从cljs代码中调用它:
;;ex: macro.clj
(defmacro get-project-version [] 
  (System/getProperty "penelope.version"))

;;my_logic_code.cljs
(ns my-logic-code
  (:require-macros [macros :as m]))

(def project-version (m/get-project-version))

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