Getting the version of the current clojure project in the repl
Asked Answered
M

8

24

Is it possible to grab the project information within the clojure repl?

For example, if there was a project defined:

(defproject blahproject "0.1.2" ....)

When running a repl in the project directory, is there a function like this?

> (project-version) 
;=> 0.1.2 
Mcarthur answered 29/4, 2013 at 3:30 Comment(1)
If you just want the project version, it is mentioned here: #11235945Tameratamerlane
C
14

Leiningen project files are just Clojure data :)

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

Carotenoid answered 29/4, 2013 at 6:20 Comment(3)
Just use (some-> (io/resource "project.clj") slurp edn/read-string (nth 2))Pagination
@Pagination Chances of getting arbitrary project.clj from your classpath considered high. I got clj-time/clj-time and I haven't even explicitly pulled in that library. Be careful reaching into darkened boxes to withdraw an item at random.Conah
@Conah Good point. If you built your jar with lein then you can also use (some->> (io/resource "META-INF/maven/myproject/myproject/pom.properties") slurp (re-find #"version=(.*)") second)Pagination
O
18

While you can parse project.clj yourself, this may be annoying. It's also a lot of work. Instead, you can just do:

(System/getProperty "projectname.version")
Oyez answered 8/10, 2014 at 4:1 Comment(2)
Works from the repl, but not in an uberjar.Regenerative
@DanRoss so this could be used to detect if the current program was started from a repl? Or is there an easier/more reliable way?Ferrick
C
14

Leiningen project files are just Clojure data :)

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

Carotenoid answered 29/4, 2013 at 6:20 Comment(3)
Just use (some-> (io/resource "project.clj") slurp edn/read-string (nth 2))Pagination
@Pagination Chances of getting arbitrary project.clj from your classpath considered high. I got clj-time/clj-time and I haven't even explicitly pulled in that library. Be careful reaching into darkened boxes to withdraw an item at random.Conah
@Conah Good point. If you built your jar with lein then you can also use (some->> (io/resource "META-INF/maven/myproject/myproject/pom.properties") slurp (re-find #"version=(.*)") second)Pagination
W
11

I use environ (https://github.com/weavejester/environ) which sucks in settings from a number of sources, including system properties. The project version appears as :<project-name>-version:

foobar.repl=> (require '[environ.core :refer [env]])
nil
foobar.repl=> (:foobar-version env)
"0.1.0-SNAPSHOT"
Wedlock answered 29/1, 2015 at 21:49 Comment(0)
Q
9

Add the below code to the end of project.clj:

(def project (assoc-in project [:repl-options :init]
                       `(~'def ~'project-version ~(project :version))))

Now you will have a var called project-version in the initial namespace for the repl.

Quintinquintina answered 29/4, 2013 at 8:30 Comment(0)
H
9

As described in this discussion.

(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
Hennie answered 11/10, 2015 at 22:31 Comment(0)
M
7

As vemv said, Leiningen project files are just Clojure data. So, it's easy to access your project as an ordinary hash-map:

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

If you need this variable only in your repl, you can add it to repl-options to your project.clj:

(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))})

Now, you have project variable in your repl. So, to access the version of your project you can simply type (:version project).

Of course, you can simply use native Leiningen code to parse you project file:

(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)))})

But, if you need only the version of your project and nothing more, then it's best to use Ankur's solution.

Marginal answered 29/4, 2013 at 9:15 Comment(0)
T
7

For a more fully-featured approach, you might want to take a look at the configleaf plugin for Leiningen (https://github.com/davidsantiago/configleaf). It will make the project map, with active profiles merged in, available to project code in a namespace of your choosing.

Terrilyn answered 29/4, 2013 at 17:4 Comment(0)
M
0

In case you need to do this from clojurescript you could create a macro (from another clj file) and call it from the cljs code :

;;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))
Mansell answered 11/9, 2020 at 14:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.