14
votes

I've got a two profiles defined in project.clj, one locally, one for testing on travis:

:profiles {:dev {:dependencies [[midje "1.6.0"]
                                [mysql/mysql-connector-java "5.1.25"]]
                 :plugins [[lein-midje "3.1.3"]]
                 :user "root" :pass "root"}
           :travis {:user "travis" :pass ""}}

I'm hoping to be able to get access to the :user and :pass values in my projects. How can this be done?

Update:

I also want to be able to use the lein with-profile command... so my tests would have:

lein with-profile dev test

-> would use "root", "root" credentials

lein with-profile dev,travis test

-> would use "travis", "" credentials

2
I think this problem it's resolved here stackoverflow.com/questions/16270805/…tangrammer

2 Answers

15
votes

If you don't need the values defined in project.clj for anything else (IE, you're free to choose the representation) consider Environ.

You can then define the following in your project.clj

:profiles {:dev {:env {:user "root" :pass "root"}}}

and read the values:

(use 'environ.core)

(def creds
  {:user (env :user)
   :pass (env :pass)})

This has the advantage that you can also specify the values using environment variables and system properties.

7
votes

Leiningen's build file is Clojure code so you can just read it in:

(->> "project.clj" slurp read-string (drop 3) (partition 2) (map vec) (into {})
     :profiles :dev)
; => {:dependencies [[midje "1.5.1"] [ring-server "0.2.8"]], :plugins [[lein-midje "3.1.0"]]}

If you need heavier functionalities (such as access to the final project map) then something like configleaf might be better suited.

Another way to manage this (which I've utilized quite often) is to have a separate config file for profile specific data:

example/profiles/travis/example/config.clj:

(ns example.config)

(def user "travis")
(def pass "")

example/dev-resources/example/config.clj:

(ns example.config)

(def user "root")
(def pass "root")

example/src/example/core.clj:

(ns example.core
  (:require [example.config :as config]))

(println config/user)

And you need to add the profile specific resource path to your project.clj:

:profiles {:travis {:resource-paths ["profiles/travis/"]}}